# HG changeset patch # User yz147064 # Date 1174495738 25200 # Node ID 5a1dfce6c5cc465652da4be69527cd799b43f508 # Parent b083fcb4e28781e0d74bd01cd2a90aac255027af PSARC 2007/140 libdladm restructure 6329535 the use_cache argument of macadm_walk function should be removed 6454340 macadm_walk leaks 6509525 wrong error code when adding/removing ports to/from an aggregation 6509532 aggregation deleting fails but system reports success 6518572 the reference to dls_vlan should be released if setzoneid fails 6520149 show-linkprop stops showing full list of link properties if it fails to display one property 6535220 potential complicated library dependency and code duplication between libdladm and its friends diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/liblaadm/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/liblaadm/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,62 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include $(SRC)/lib/Makefile.lib + +HDRS = liblaadm.h +HDRDIR = common + +SUBDIRS = $(MACH) + +POFILE = liblaadm.po +MSGFILES = common/liblaadm.c + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +check: $(CHECKHDRS) + +$(POFILE): pofile_MSGFILES + +_msg: $(MSGDOMAINPOFILE) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/Makefile.msg.targ +include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/liblaadm/Makefile.com --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/liblaadm/Makefile.com Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,53 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = liblaadm.a +VERS = .1 +OBJECTS = liblaadm.o + +include ../../Makefile.lib + +# install this library in the root filesystem +include ../../Makefile.rootfs + +LIBS = $(DYNLIB) $(LINTLIB) + +LDLIBS += -lsocket -lc + +SRCDIR = ../common +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) -D_REENTRANT + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/liblaadm/common/llib-llaadm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/liblaadm/common/llib-llaadm Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,32 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ +/*PROTOLIB1*/ + +#include diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/liblaadm/common/mapfile-vers --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/liblaadm/common/mapfile-vers Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,49 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +SUNWprivate_1.1 { + global: + laadm_add; + laadm_create; + laadm_delete; + laadm_diag; + laadm_down; + laadm_lacp_mode_to_str; + laadm_lacp_timer_to_str; + laadm_mac_addr_to_str; + laadm_modify; + laadm_policy_to_str; + laadm_remove; + laadm_str_to_lacp_mode; + laadm_str_to_lacp_timer; + laadm_str_to_mac_addr; + laadm_str_to_policy; + laadm_up; + laadm_walk_sys; + local: + *; +}; diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/liblaadm/i386/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/liblaadm/i386/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/liblaadm/sparc/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/liblaadm/sparc/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libmacadm/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libmacadm/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,62 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include $(SRC)/lib/Makefile.lib + +HDRS = libmacadm.h +HDRDIR = common + +SUBDIRS = $(MACH) + +POFILE = libmacadm.po +MSGFILES = common/libmacadm.c + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +check: $(CHECKHDRS) + +$(POFILE): pofile_MSGFILES + +_msg: $(MSGDOMAINPOFILE) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/Makefile.msg.targ +include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libmacadm/Makefile.com --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libmacadm/Makefile.com Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,53 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libmacadm.a +VERS = .1 +OBJECTS = libmacadm.o + +include ../../Makefile.lib + +# install this library in the root filesystem +include ../../Makefile.rootfs + +LIBS = $(DYNLIB) $(LINTLIB) + +LDLIBS += -ldevinfo -lc + +SRCDIR = ../common +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) -D_REENTRANT + +.KEEP_STATE: + +all: $(LIBS) fnamecheck + +lint: lintcheck + +include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libmacadm/common/libmacadm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libmacadm/common/libmacadm.c Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,137 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _KERNEL +#include +#undef _KERNEL + +/* + * MAC Administration Library. + * + * This library is used by administration tools such as dladm(1M) to + * iterate through the list of MAC interfaces + * + */ + +typedef struct macadm_dev { + char md_name[MAXNAMELEN]; + struct macadm_dev *md_next; +} macadm_dev_t; + +typedef struct macadm_walk { + macadm_dev_t *mw_dev_list; +} macadm_walk_t; + +/* + * Local callback invoked for each DDI_NT_NET node. + */ +/* ARGSUSED */ +static int +i_macadm_apply(di_node_t node, di_minor_t minor, void *arg) +{ + macadm_walk_t *mwp = arg; + macadm_dev_t *mdp = mwp->mw_dev_list; + macadm_dev_t **lastp = &mwp->mw_dev_list; + char dev[MAXNAMELEN]; + + (void) snprintf(dev, MAXNAMELEN, "%s%d", + di_driver_name(node), di_instance(node)); + + /* + * Skip aggregations. + */ + if (strcmp("aggr", di_driver_name(node)) == 0) + return (DI_WALK_CONTINUE); + + while (mdp) { + /* + * Skip duplicates. + */ + if (strcmp(mdp->md_name, dev) == 0) + return (DI_WALK_CONTINUE); + + lastp = &mdp->md_next; + mdp = mdp->md_next; + } + + if ((mdp = malloc(sizeof (*mdp))) == NULL) + return (DI_WALK_CONTINUE); + + (void) strlcpy(mdp->md_name, dev, MAXNAMELEN); + mdp->md_next = NULL; + *lastp = mdp; + + return (DI_WALK_CONTINUE); +} + +/* + * Invoke the specified callback for each DDI_NT_MAC node. + */ +int +macadm_walk(void (*fn)(void *, const char *), void *arg, + boolean_t use_cache) +{ + di_node_t root; + macadm_walk_t mw; + macadm_dev_t *mdp; + uint_t flags; + + if (use_cache) { + flags = DINFOCACHE; + } else { + flags = DINFOSUBTREE | DINFOMINOR | DINFOPROP | DINFOFORCE; + } + + if ((root = di_init("/", flags)) == DI_NODE_NIL) { + return (-1); + } + mw.mw_dev_list = NULL; + + (void) di_walk_minor(root, DDI_NT_NET, DI_CHECK_ALIAS, &mw, + i_macadm_apply); + + di_fini(root); + + mdp = mw.mw_dev_list; + while (mdp) { + (*fn)(arg, mdp->md_name); + mdp = mdp->md_next; + } + + return (0); +} diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libmacadm/common/libmacadm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libmacadm/common/libmacadm.h Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,46 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LIBMACADM_H +#define _LIBMACADM_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern int macadm_walk(void (*)(void *, const char *), + void *, boolean_t); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBMACADM_H */ diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libmacadm/common/llib-lmacadm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libmacadm/common/llib-lmacadm Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,32 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ +/*PROTOLIB1*/ + +#include diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libmacadm/common/mapfile-vers --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libmacadm/common/mapfile-vers Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +SUNWprivate_1.1 { + global: + macadm_walk; + local: + *; +}; diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libmacadm/i386/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libmacadm/i386/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libmacadm/sparc/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libmacadm/sparc/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libwladm/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libwladm/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,63 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include $(SRC)/lib/Makefile.lib + +HDRS = libwladm.h libwladm_impl.h +HDRDIR = common + +SUBDIRS = $(MACH) + +POFILE = libwladm.po +MSGFILES = common/libwladm.c +XGETFLAGS = -a -x libwladm.xcl + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +check: $(CHECKHDRS) + +$(POFILE): pofile_MSGFILES + +_msg: $(MSGDOMAINPOFILE) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/Makefile.msg.targ +include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libwladm/Makefile.com --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libwladm/Makefile.com Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,51 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libwladm.a +VERS = .1 +OBJECTS = libwladm.o + +include ../../Makefile.lib +# install this library in the root filesystem +include ../../Makefile.rootfs + +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += -ldevinfo -lsocket -lc + +SRCDIR = ../common +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) -D_REENTRANT + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libwladm/common/llib-lwladm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libwladm/common/llib-lwladm Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,31 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ +/*PROTOLIB1*/ + +#include diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libwladm/common/mapfile-vers --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libwladm/common/mapfile-vers Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,60 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +SUNWprivate_1.1 { + global: + wladm_scan; + wladm_connect; + wladm_disconnect; + wladm_get_link_attr; + wladm_walk; + wladm_is_valid; + wladm_set_prop; + wladm_walk_prop; + wladm_get_prop; + wladm_essid2str; + wladm_bssid2str; + wladm_secmode2str; + wladm_strength2str; + wladm_mode2str; + wladm_speed2str; + wladm_auth2str; + wladm_bsstype2str; + wladm_linkstatus2str; + wladm_status2str; + wladm_str2essid; + wladm_str2bssid; + wladm_str2secmode; + wladm_str2strength; + wladm_str2mode; + wladm_str2speed; + wladm_str2auth; + wladm_str2bsstype; + wladm_str2linkstatus; + local: + *; +}; diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libwladm/i386/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libwladm/i386/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libwladm/libwladm.xcl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libwladm/libwladm.xcl Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,52 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +msgid "a" +msgid "b" +msgid "g" +msgid "channel" +msgid "powermode" +msgid "radio" +msgid "speed" +msgid "" +msgid "%.*f" +msgid "%d" +msgid "%s" +msgid "%s%d" +msgid "%u" +msgid "/" +msgid "/dev/%s" +msgid "open" +msgid "shared" +msgid "bss" +msgid "ibss" +msgid "any" +msgid "on" +msgid "off" +msgid "fast" +msgid "max" +msgid "wep" +msgid "none" diff -r b083fcb4e287 -r 5a1dfce6c5cc deleted_files/usr/src/lib/libwladm/sparc/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deleted_files/usr/src/lib/libwladm/sparc/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/Makefile.lint --- a/usr/src/Makefile.lint Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/Makefile.lint Wed Mar 21 09:48:58 2007 -0700 @@ -337,10 +337,8 @@ lib/libiscsitgt \ lib/libkmf \ lib/libkstat \ - lib/liblaadm \ lib/liblgrp \ lib/liblm \ - lib/libmacadm \ lib/libmalloc \ lib/libmapmalloc \ lib/libmapid \ @@ -378,7 +376,6 @@ lib/libuutil \ lib/libwanboot \ lib/libwanbootutil \ - lib/libwladm \ lib/libxnet \ lib/libzfs \ lib/libzfs_jni \ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/cmd/dladm/Makefile --- a/usr/src/cmd/dladm/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/cmd/dladm/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -35,8 +35,7 @@ include ../Makefile.cmd XGETFLAGS += -a -x $(PROG).xcl -LDLIBS += -ldladm -lmacadm -ldlpi -llaadm -lkstat -lwladm -lsecdb -lbsm \ - -linetutil +LDLIBS += -ldladm -ldlpi -lkstat -lsecdb -lbsm -linetutil $(ROOTCFGFILES) := OWNER= dladm $(ROOTCFGFILES) := GROUP= sys diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/cmd/dladm/dladm.c --- a/usr/src/cmd/dladm/dladm.c Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/cmd/dladm/dladm.c Wed Mar 21 09:48:58 2007 -0700 @@ -46,10 +46,9 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include #include #include #include @@ -93,18 +92,6 @@ boolean_t ms_parseable; } show_mac_state_t; -typedef struct port_state { - char *state_name; - aggr_port_state_t state_num; -} port_state_t; - -static port_state_t port_states[] = { - {"standby", AGGR_PORT_STATE_STANDBY }, - {"attached", AGGR_PORT_STATE_ATTACHED } -}; - -#define NPORTSTATES (sizeof (port_states) / sizeof (port_state_t)) - typedef void cmdfunc_t(int, char **); static cmdfunc_t do_show_link, do_show_dev, do_show_wifi; @@ -124,20 +111,17 @@ static void get_mac_stats(const char *, pktsum_t *); static void get_link_stats(const char *, pktsum_t *); static uint64_t mac_ifspeed(const char *); -static char *mac_link_state(const char *); -static char *mac_link_duplex(const char *); static void stats_total(pktsum_t *, pktsum_t *, pktsum_t *); static void stats_diff(pktsum_t *, pktsum_t *, pktsum_t *); +static const char *mac_link_state(const char *); +static const char *mac_link_duplex(const char *); static boolean_t str2int(const char *, int *); static void die(const char *, ...); static void die_optdup(int); static void die_opterr(int, int); -static void die_laerr(laadm_diag_t, const char *, ...); -static void die_wlerr(wladm_status_t, const char *, ...); static void die_dlerr(dladm_status_t, const char *, ...); static void warn(const char *, ...); -static void warn_wlerr(wladm_status_t, const char *, ...); static void warn_dlerr(dladm_status_t, const char *, ...); typedef struct cmd { @@ -292,22 +276,22 @@ static void do_create_aggr(int argc, char *argv[]) { - char option; - int key; - uint32_t policy = AGGR_POLICY_L4; - aggr_lacp_mode_t lacp_mode = AGGR_LACP_OFF; - aggr_lacp_timer_t lacp_timer = AGGR_LACP_TIMER_SHORT; - laadm_port_attr_db_t port[MAXPORT]; - uint_t nport = 0; - uint8_t mac_addr[ETHERADDRL]; - boolean_t mac_addr_fixed = B_FALSE; - boolean_t P_arg = B_FALSE; - boolean_t l_arg = B_FALSE; - boolean_t t_arg = B_FALSE; - boolean_t u_arg = B_FALSE; - boolean_t T_arg = B_FALSE; - char *altroot = NULL; - laadm_diag_t diag = 0; + char option; + int key; + uint32_t policy = AGGR_POLICY_L4; + aggr_lacp_mode_t lacp_mode = AGGR_LACP_OFF; + aggr_lacp_timer_t lacp_timer = AGGR_LACP_TIMER_SHORT; + dladm_aggr_port_attr_db_t port[MAXPORT]; + uint_t nport = 0; + uint8_t mac_addr[ETHERADDRL]; + boolean_t mac_addr_fixed = B_FALSE; + boolean_t P_arg = B_FALSE; + boolean_t l_arg = B_FALSE; + boolean_t t_arg = B_FALSE; + boolean_t u_arg = B_FALSE; + boolean_t T_arg = B_FALSE; + char *altroot = NULL; + dladm_status_t status; opterr = 0; while ((option = getopt_long(argc, argv, ":d:l:P:R:tu:T:", @@ -328,7 +312,7 @@ die_optdup(option); P_arg = B_TRUE; - if (!laadm_str_to_policy(optarg, &policy)) + if (!dladm_aggr_str2policy(optarg, &policy)) die("invalid policy '%s'", optarg); break; case 'u': @@ -336,7 +320,7 @@ die_optdup(option); u_arg = B_TRUE; - if (!laadm_str_to_mac_addr(optarg, &mac_addr_fixed, + if (!dladm_aggr_str2macaddr(optarg, &mac_addr_fixed, mac_addr)) die("invalid MAC address '%s'", optarg); break; @@ -345,7 +329,7 @@ die_optdup(option); l_arg = B_TRUE; - if (!laadm_str_to_lacp_mode(optarg, &lacp_mode)) + if (!dladm_aggr_str2lacpmode(optarg, &lacp_mode)) die("invalid LACP mode '%s'", optarg); break; case 'T': @@ -353,7 +337,7 @@ die_optdup(option); T_arg = B_TRUE; - if (!laadm_str_to_lacp_timer(optarg, &lacp_timer)) + if (!dladm_aggr_str2lacptimer(optarg, &lacp_timer)) die("invalid LACP timer value '%s'", optarg); break; case 't': @@ -378,9 +362,10 @@ if (!str2int(argv[optind], &key) || key < 1) die("invalid key value '%s'", argv[optind]); - if (laadm_create(key, nport, port, policy, mac_addr_fixed, - mac_addr, lacp_mode, lacp_timer, t_arg, altroot, &diag) < 0) - die_laerr(diag, "create operation failed"); + status = dladm_aggr_create(key, nport, port, policy, mac_addr_fixed, + mac_addr, lacp_mode, lacp_timer, t_arg, altroot); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "create operation failed"); } static void @@ -390,7 +375,7 @@ char option; boolean_t t_arg = B_FALSE; char *altroot = NULL; - laadm_diag_t diag = 0; + dladm_status_t status; opterr = 0; while ((option = getopt_long(argc, argv, ":R:t", longopts, @@ -415,20 +400,21 @@ if (!str2int(argv[optind], &key) || key < 1) die("invalid key value '%s'", argv[optind]); - if (laadm_delete(key, t_arg, altroot, &diag) < 0) - die_laerr(diag, "delete operation failed"); + status = dladm_aggr_delete(key, t_arg, altroot); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "delete operation failed"); } static void do_add_aggr(int argc, char *argv[]) { - char option; - int key; - laadm_port_attr_db_t port[MAXPORT]; - uint_t nport = 0; - boolean_t t_arg = B_FALSE; - char *altroot = NULL; - laadm_diag_t diag = 0; + char option; + int key; + dladm_aggr_port_attr_db_t port[MAXPORT]; + uint_t nport = 0; + boolean_t t_arg = B_FALSE; + char *altroot = NULL; + dladm_status_t status; opterr = 0; while ((option = getopt_long(argc, argv, ":d:R:t", longopts, @@ -466,32 +452,33 @@ if (!str2int(argv[optind], &key) || key < 1) die("invalid key value '%s'", argv[optind]); - if (laadm_add(key, nport, port, t_arg, altroot, &diag) < 0) { + status = dladm_aggr_add(key, nport, port, t_arg, altroot); + if (status != DLADM_STATUS_OK) { /* - * checking ENOTSUP is a temporary workaround + * checking DLADM_STATUS_NOTSUP is a temporary workaround * and should be removed once 6399681 is fixed. */ - if (errno == ENOTSUP) { + if (status == DLADM_STATUS_NOTSUP) { (void) fprintf(stderr, gettext("%s: add operation failed: %s\n"), progname, gettext("device capabilities don't match")); exit(ENOTSUP); } - die_laerr(diag, "add operation failed"); + die_dlerr(status, "add operation failed"); } } static void do_remove_aggr(int argc, char *argv[]) { - char option; - int key; - laadm_port_attr_db_t port[MAXPORT]; - uint_t nport = 0; - boolean_t t_arg = B_FALSE; - char *altroot = NULL; - laadm_diag_t diag = 0; + char option; + int key; + dladm_aggr_port_attr_db_t port[MAXPORT]; + uint_t nport = 0; + boolean_t t_arg = B_FALSE; + char *altroot = NULL; + dladm_status_t status; opterr = 0; while ((option = getopt_long(argc, argv, ":d:R:t", @@ -529,8 +516,9 @@ if (!str2int(argv[optind], &key) || key < 1) die("invalid key value '%s'", argv[optind]); - if (laadm_remove(key, nport, port, t_arg, altroot, &diag) < 0) - die_laerr(diag, "remove operation failed"); + status = dladm_aggr_remove(key, nport, port, t_arg, altroot); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "remove operation failed"); } static void @@ -546,47 +534,47 @@ uint8_t modify_mask = 0; boolean_t t_arg = B_FALSE; char *altroot = NULL; - laadm_diag_t diag = 0; + dladm_status_t status; opterr = 0; while ((option = getopt_long(argc, argv, ":l:P:R:tu:T:", longopts, NULL)) != -1) { switch (option) { case 'P': - if (modify_mask & LAADM_MODIFY_POLICY) + if (modify_mask & DLADM_AGGR_MODIFY_POLICY) die_optdup(option); - modify_mask |= LAADM_MODIFY_POLICY; - - if (!laadm_str_to_policy(optarg, &policy)) + modify_mask |= DLADM_AGGR_MODIFY_POLICY; + + if (!dladm_aggr_str2policy(optarg, &policy)) die("invalid policy '%s'", optarg); break; case 'u': - if (modify_mask & LAADM_MODIFY_MAC) + if (modify_mask & DLADM_AGGR_MODIFY_MAC) die_optdup(option); - modify_mask |= LAADM_MODIFY_MAC; - - if (!laadm_str_to_mac_addr(optarg, &mac_addr_fixed, + modify_mask |= DLADM_AGGR_MODIFY_MAC; + + if (!dladm_aggr_str2macaddr(optarg, &mac_addr_fixed, mac_addr)) die("invalid MAC address '%s'", optarg); break; case 'l': - if (modify_mask & LAADM_MODIFY_LACP_MODE) + if (modify_mask & DLADM_AGGR_MODIFY_LACP_MODE) die_optdup(option); - modify_mask |= LAADM_MODIFY_LACP_MODE; - - if (!laadm_str_to_lacp_mode(optarg, &lacp_mode)) + modify_mask |= DLADM_AGGR_MODIFY_LACP_MODE; + + if (!dladm_aggr_str2lacpmode(optarg, &lacp_mode)) die("invalid LACP mode '%s'", optarg); break; case 'T': - if (modify_mask & LAADM_MODIFY_LACP_TIMER) + if (modify_mask & DLADM_AGGR_MODIFY_LACP_TIMER) die_optdup(option); - modify_mask |= LAADM_MODIFY_LACP_TIMER; - - if (!laadm_str_to_lacp_timer(optarg, &lacp_timer)) + modify_mask |= DLADM_AGGR_MODIFY_LACP_TIMER; + + if (!dladm_aggr_str2lacptimer(optarg, &lacp_timer)) die("invalid LACP timer value '%s'", optarg); break; case 't': @@ -611,16 +599,17 @@ if (!str2int(argv[optind], &key) || key < 1) die("invalid key value '%s'", argv[optind]); - if (laadm_modify(key, modify_mask, policy, mac_addr_fixed, mac_addr, - lacp_mode, lacp_timer, t_arg, altroot, &diag) < 0) - die_laerr(diag, "modify operation failed"); + status = dladm_aggr_modify(key, modify_mask, policy, mac_addr_fixed, + mac_addr, lacp_mode, lacp_timer, t_arg, altroot); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "modify operation failed"); } static void do_up_aggr(int argc, char *argv[]) { int key = 0; - laadm_diag_t diag = 0; + dladm_status_t status; /* get aggregation key (optional last argument) */ if (argc == 2) { @@ -630,12 +619,12 @@ usage(); } - if (laadm_up(key, NULL, &diag) < 0) { + if ((status = dladm_aggr_up(key, NULL)) != DLADM_STATUS_OK) { if (key != 0) { - die_laerr(diag, "could not bring up aggregation '%u'", + die_dlerr(status, "could not bring up aggregation '%u'", key); } else { - die_laerr(diag, "could not bring aggregations up"); + die_dlerr(status, "could not bring aggregations up"); } } } @@ -643,7 +632,8 @@ static void do_down_aggr(int argc, char *argv[]) { - int key = 0; + dladm_status_t status; + int key = 0; /* get aggregation key (optional last argument) */ if (argc == 2) { @@ -653,13 +643,12 @@ usage(); } - if (laadm_down(key) < 0) { + if ((status = dladm_aggr_down(key)) != DLADM_STATUS_OK) { if (key != 0) { - die("could not bring down aggregation '%u': %s", - key, strerror(errno)); + die_dlerr(status, + "could not bring down aggregation '%u'", key); } else { - die("could not bring down aggregations: %s", - strerror(errno)); + die_dlerr(status, "could not bring down aggregations"); } } } @@ -819,9 +808,9 @@ } static void -dump_grp(laadm_grp_attr_sys_t *grp, boolean_t parseable) +dump_grp(dladm_aggr_grp_attr_t *grp, boolean_t parseable) { - char policy_str[LAADM_POLICY_STR_LEN]; + char buf[DLADM_STRSIZE]; char addr_str[ETHERADDRL * 3]; if (!parseable) { @@ -829,19 +818,19 @@ grp->lg_key, grp->lg_key); (void) printf(gettext("\tpolicy: %s"), - laadm_policy_to_str(grp->lg_policy, policy_str)); + dladm_aggr_policy2str(grp->lg_policy, buf)); (void) printf(gettext("\taddress: %s (%s)\n"), - laadm_mac_addr_to_str(grp->lg_mac, addr_str), + dladm_aggr_macaddr2str(grp->lg_mac, addr_str), (grp->lg_mac_fixed) ? gettext("fixed") : gettext("auto")); } else { (void) printf("aggr key=%d", grp->lg_key); (void) printf(" policy=%s", - laadm_policy_to_str(grp->lg_policy, policy_str)); + dladm_aggr_policy2str(grp->lg_policy, buf)); (void) printf(" address=%s", - laadm_mac_addr_to_str(grp->lg_mac, addr_str)); + dladm_aggr_macaddr2str(grp->lg_mac, addr_str)); (void) printf(" address-type=%s\n", (grp->lg_mac_fixed) ? "fixed" : "auto"); @@ -849,11 +838,13 @@ } static void -dump_grp_lacp(laadm_grp_attr_sys_t *grp, boolean_t parseable) +dump_grp_lacp(dladm_aggr_grp_attr_t *grp, boolean_t parseable) { - const char *lacp_mode_str = laadm_lacp_mode_to_str(grp->lg_lacp_mode); - const char *lacp_timer_str = - laadm_lacp_timer_to_str(grp->lg_lacp_timer); + char lacp_mode_str[DLADM_STRSIZE]; + char lacp_timer_str[DLADM_STRSIZE]; + + (void) dladm_aggr_lacpmode2str(grp->lg_lacp_mode, lacp_mode_str); + (void) dladm_aggr_lacptimer2str(grp->lg_lacp_timer, lacp_timer_str); if (!parseable) { (void) printf(gettext("\t\tLACP mode: %s"), lacp_mode_str); @@ -865,7 +856,7 @@ } static void -dump_grp_stats(laadm_grp_attr_sys_t *grp) +dump_grp_stats(dladm_aggr_grp_attr_t *grp) { (void) printf("key: %d", grp->lg_key); (void) printf("\tipackets rbytes opackets obytes "); @@ -888,49 +879,37 @@ "state\n")); } -static char * -port_state_to_str(aggr_port_state_t state_num) -{ - int i; - port_state_t *state; - - for (i = 0; i < NPORTSTATES; i++) { - state = &port_states[i]; - if (state->state_num == state_num) - return (state->state_name); - } - - return ("unknown"); -} - static void -dump_port(laadm_port_attr_sys_t *port, boolean_t parseable) +dump_port(dladm_aggr_port_attr_t *port, boolean_t parseable) { char *dev = port->lp_devname; - char buf[ETHERADDRL * 3]; + char mac_addr[ETHERADDRL * 3]; + char buf[DLADM_STRSIZE]; if (!parseable) { - (void) printf(" %-9s\t%s", dev, laadm_mac_addr_to_str( - port->lp_mac, buf)); + (void) printf(" %-9s\t%s", dev, dladm_aggr_macaddr2str( + port->lp_mac, mac_addr)); (void) printf("\t %5uMb", (int)(mac_ifspeed(dev) / 1000000ull)); (void) printf("\t%s", mac_link_duplex(dev)); (void) printf("\t%s", mac_link_state(dev)); - (void) printf("\t%s\n", port_state_to_str(port->lp_state)); + (void) printf("\t%s\n", + dladm_aggr_portstate2str(port->lp_state, buf)); } else { (void) printf(" device=%s address=%s", dev, - laadm_mac_addr_to_str(port->lp_mac, buf)); + dladm_aggr_macaddr2str(port->lp_mac, mac_addr)); (void) printf(" speed=%u", (int)(mac_ifspeed(dev) / 1000000ull)); (void) printf(" duplex=%s", mac_link_duplex(dev)); (void) printf(" link=%s", mac_link_state(dev)); - (void) printf(" port=%s", port_state_to_str(port->lp_state)); + (void) printf(" port=%s", + dladm_aggr_portstate2str(port->lp_state, buf)); } } static void -dump_port_lacp(laadm_port_attr_sys_t *port) +dump_port_lacp(dladm_aggr_port_attr_t *port) { aggr_lacp_state_t *state = &port->lp_lacp_state; @@ -977,7 +956,7 @@ } static int -show_key(void *arg, laadm_grp_attr_sys_t *grp) +show_key(void *arg, dladm_aggr_grp_attr_t *grp) { show_grp_state_t *state = (show_grp_state_t *)arg; int i; @@ -1256,7 +1235,7 @@ state.gs_key = key; state.gs_found = B_FALSE; - (void) laadm_walk_sys(show_key, &state); + (void) dladm_aggr_walk(show_key, &state); if (key != 0 && !state.gs_found) die("non-existent aggregation key '%u'", key); @@ -1332,7 +1311,7 @@ } if (dev == NULL) - (void) macadm_walk(show_dev, &state, B_TRUE); + (void) dladm_mac_walk(show_dev, &state); else show_dev(&state, dev); } @@ -1391,7 +1370,7 @@ for (;;) { state.gs_found = B_FALSE; - (void) laadm_walk_sys(show_key, &state); + (void) dladm_aggr_walk(show_key, &state); if (state.gs_key != 0 && !state.gs_found) die("non-existent aggregation key '%u'", key); @@ -1423,7 +1402,7 @@ state.ms_donefirst = B_FALSE; if (dev == NULL) - (void) macadm_walk(show_dev_stats, &state, B_TRUE); + (void) dladm_mac_walk(show_dev_stats, &state); else show_dev_stats(&state, dev); @@ -1596,55 +1575,33 @@ return (ifspeed); } -static char * +static const char * mac_link_state(const char *dev) { link_state_t link_state; - char *state_str = "unknown"; + char buf[DLADM_STRSIZE]; if (get_single_mac_stat(dev, "link_state", KSTAT_DATA_UINT32, &link_state) != 0) { - return (state_str); + return ("unknown"); } - switch (link_state) { - case LINK_STATE_UP: - state_str = "up"; - break; - case LINK_STATE_DOWN: - state_str = "down"; - break; - default: - break; - } - - return (state_str); + return (dladm_linkstate2str(link_state, buf)); } -static char * +static const char * mac_link_duplex(const char *dev) { link_duplex_t link_duplex; - char *duplex_str = "unknown"; + char buf[DLADM_STRSIZE]; if (get_single_mac_stat(dev, "link_duplex", KSTAT_DATA_UINT32, &link_duplex) != 0) { - return (duplex_str); + return ("unknown"); } - switch (link_duplex) { - case LINK_DUPLEX_FULL: - duplex_str = "full"; - break; - case LINK_DUPLEX_HALF: - duplex_str = "half"; - break; - default: - break; - } - - return (duplex_str); + return (dladm_linkduplex2str(link_duplex, buf)); } #define WIFI_CMD_SCAN 0x00000001 @@ -1659,17 +1616,17 @@ } wifi_field_t; static wifi_field_t wifi_fields[] = { -{ "link", "LINK", 10, 0, WIFI_CMD_ALL}, -{ "essid", "ESSID", 19, WLADM_WLAN_ATTR_ESSID, WIFI_CMD_ALL}, -{ "bssid", "BSSID/IBSSID", 17, WLADM_WLAN_ATTR_BSSID, WIFI_CMD_ALL}, -{ "ibssid", "BSSID/IBSSID", 17, WLADM_WLAN_ATTR_BSSID, WIFI_CMD_ALL}, -{ "mode", "MODE", 6, WLADM_WLAN_ATTR_MODE, WIFI_CMD_ALL}, -{ "speed", "SPEED", 6, WLADM_WLAN_ATTR_SPEED, WIFI_CMD_ALL}, -{ "auth", "AUTH", 8, WLADM_WLAN_ATTR_AUTH, WIFI_CMD_SHOW}, -{ "bsstype", "BSSTYPE", 8, WLADM_WLAN_ATTR_BSSTYPE, WIFI_CMD_ALL}, -{ "sec", "SEC", 6, WLADM_WLAN_ATTR_SECMODE, WIFI_CMD_ALL}, -{ "status", "STATUS", 17, WLADM_LINK_ATTR_STATUS, WIFI_CMD_SHOW}, -{ "strength", "STRENGTH", 10, WLADM_WLAN_ATTR_STRENGTH, WIFI_CMD_ALL}} +{ "link", "LINK", 10, 0, WIFI_CMD_ALL}, +{ "essid", "ESSID", 19, DLADM_WLAN_ATTR_ESSID, WIFI_CMD_ALL}, +{ "bssid", "BSSID/IBSSID", 17, DLADM_WLAN_ATTR_BSSID, WIFI_CMD_ALL}, +{ "ibssid", "BSSID/IBSSID", 17, DLADM_WLAN_ATTR_BSSID, WIFI_CMD_ALL}, +{ "mode", "MODE", 6, DLADM_WLAN_ATTR_MODE, WIFI_CMD_ALL}, +{ "speed", "SPEED", 6, DLADM_WLAN_ATTR_SPEED, WIFI_CMD_ALL}, +{ "auth", "AUTH", 8, DLADM_WLAN_ATTR_AUTH, WIFI_CMD_SHOW}, +{ "bsstype", "BSSTYPE", 8, DLADM_WLAN_ATTR_BSSTYPE, WIFI_CMD_ALL}, +{ "sec", "SEC", 6, DLADM_WLAN_ATTR_SECMODE, WIFI_CMD_ALL}, +{ "status", "STATUS", 17, DLADM_WLAN_LINKATTR_STATUS, WIFI_CMD_SHOW}, +{ "strength", "STRENGTH", 10, DLADM_WLAN_ATTR_STRENGTH, WIFI_CMD_ALL}} ; static char *all_scan_wifi_fields = @@ -1853,9 +1810,9 @@ static void print_wlan_attr(print_wifi_state_t *statep, wifi_field_t *wfp, - wladm_wlan_attr_t *attrp) + dladm_wlan_attr_t *attrp) { - char buf[WLADM_STRSIZE]; + char buf[DLADM_STRSIZE]; const char *str = ""; if (wfp->wf_mask == 0) { @@ -1869,30 +1826,30 @@ } switch (wfp->wf_mask) { - case WLADM_WLAN_ATTR_ESSID: - str = wladm_essid2str(&attrp->wa_essid, buf); + case DLADM_WLAN_ATTR_ESSID: + str = dladm_wlan_essid2str(&attrp->wa_essid, buf); break; - case WLADM_WLAN_ATTR_BSSID: - str = wladm_bssid2str(&attrp->wa_bssid, buf); + case DLADM_WLAN_ATTR_BSSID: + str = dladm_wlan_bssid2str(&attrp->wa_bssid, buf); break; - case WLADM_WLAN_ATTR_SECMODE: - str = wladm_secmode2str(&attrp->wa_secmode, buf); + case DLADM_WLAN_ATTR_SECMODE: + str = dladm_wlan_secmode2str(&attrp->wa_secmode, buf); break; - case WLADM_WLAN_ATTR_STRENGTH: - str = wladm_strength2str(&attrp->wa_strength, buf); + case DLADM_WLAN_ATTR_STRENGTH: + str = dladm_wlan_strength2str(&attrp->wa_strength, buf); break; - case WLADM_WLAN_ATTR_MODE: - str = wladm_mode2str(&attrp->wa_mode, buf); + case DLADM_WLAN_ATTR_MODE: + str = dladm_wlan_mode2str(&attrp->wa_mode, buf); break; - case WLADM_WLAN_ATTR_SPEED: - str = wladm_speed2str(&attrp->wa_speed, buf); + case DLADM_WLAN_ATTR_SPEED: + str = dladm_wlan_speed2str(&attrp->wa_speed, buf); (void) strlcat(buf, "Mb", sizeof (buf)); break; - case WLADM_WLAN_ATTR_AUTH: - str = wladm_auth2str(&attrp->wa_auth, buf); + case DLADM_WLAN_ATTR_AUTH: + str = dladm_wlan_auth2str(&attrp->wa_auth, buf); break; - case WLADM_WLAN_ATTR_BSSTYPE: - str = wladm_bsstype2str(&attrp->wa_bsstype, buf); + case DLADM_WLAN_ATTR_BSSTYPE: + str = dladm_wlan_bsstype2str(&attrp->wa_bsstype, buf); break; } @@ -1900,7 +1857,7 @@ } static boolean_t -print_scan_results(void *arg, wladm_wlan_attr_t *attrp) +print_scan_results(void *arg, dladm_wlan_attr_t *attrp) { print_wifi_state_t *statep = arg; int i; @@ -1924,26 +1881,26 @@ scan_wifi(void *arg, const char *link) { print_wifi_state_t *statep = arg; - wladm_status_t status; + dladm_status_t status; statep->ws_link = link; - status = wladm_scan(link, statep, print_scan_results); - if (status != WLADM_STATUS_OK) - die_wlerr(status, "cannot scan link '%s'", link); + status = dladm_wlan_scan(link, statep, print_scan_results); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "cannot scan link '%s'", link); return (B_TRUE); } static void print_link_attr(print_wifi_state_t *statep, wifi_field_t *wfp, - wladm_link_attr_t *attrp) + dladm_wlan_linkattr_t *attrp) { - char buf[WLADM_STRSIZE]; + char buf[DLADM_STRSIZE]; const char *str = ""; if (strcmp(wfp->wf_name, "status") == 0) { if ((wfp->wf_mask & attrp->la_valid) != 0) - str = wladm_linkstatus2str(&attrp->la_status, buf); + str = dladm_wlan_linkstatus2str(&attrp->la_status, buf); print_wifi_field(statep, wfp, str); return; } @@ -1955,12 +1912,12 @@ { int i; print_wifi_state_t *statep = arg; - wladm_link_attr_t attr; - wladm_status_t status; - - status = wladm_get_link_attr(link, &attr); - if (status != WLADM_STATUS_OK) - die_wlerr(status, "cannot get link attributes for '%s'", link); + dladm_wlan_linkattr_t attr; + dladm_status_t status; + + status = dladm_wlan_get_linkattr(link, &attr); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "cannot get link attributes for '%s'", link); if (statep->ws_header) { statep->ws_header = B_FALSE; @@ -1987,7 +1944,7 @@ boolean_t (*callback)(void *, const char *); uint_t nfields; print_wifi_state_t state; - wladm_status_t status; + dladm_status_t status; if (cmd == WIFI_CMD_SCAN) callback = scan_wifi; @@ -2029,9 +1986,9 @@ state.ws_nfields = nfields; if (state.ws_link == NULL) { - status = wladm_walk(&state, callback); - if (status != WLADM_STATUS_OK) - die_wlerr(status, "cannot walk wifi links"); + status = dladm_wlan_walk(&state, callback); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "cannot walk wifi links"); } else { (void) (*callback)(&state, state.ws_link); } @@ -2067,17 +2024,17 @@ } static int -parse_wep_keys(char *str, wladm_wep_key_t **keys, uint_t *key_countp) +parse_wep_keys(char *str, dladm_wlan_wepkey_t **keys, uint_t *key_countp) { - uint_t i; - split_t *sp; - wladm_wep_key_t *wk; - - sp = split(str, WLADM_MAX_WEPKEYS, WLADM_MAX_WEPKEYNAME_LEN); + uint_t i; + split_t *sp; + dladm_wlan_wepkey_t *wk; + + sp = split(str, DLADM_WLAN_MAX_WEPKEYS, DLADM_WLAN_MAX_WEPKEYNAME_LEN); if (sp == NULL) return (-1); - wk = malloc(sp->s_nfields * sizeof (wladm_wep_key_t)); + wk = malloc(sp->s_nfields * sizeof (dladm_wlan_wepkey_t)); if (wk == NULL) goto fail; @@ -2087,7 +2044,7 @@ dladm_status_t status; (void) strlcpy(wk[i].wk_name, sp->s_fields[i], - WLADM_MAX_WEPKEYNAME_LEN); + DLADM_WLAN_MAX_WEPKEYNAME_LEN); wk[i].wk_idx = 1; if ((s = strrchr(wk[i].wk_name, ':')) != NULL) { @@ -2097,7 +2054,7 @@ wk[i].wk_idx = (uint_t)(s[1] - '0'); *s = '\0'; } - wk[i].wk_len = WLADM_MAX_WEPKEY_LEN; + wk[i].wk_len = DLADM_WLAN_MAX_WEPKEY_LEN; status = dladm_get_secobj(wk[i].wk_name, &class, wk[i].wk_val, &wk[i].wk_len, 0); @@ -2125,14 +2082,14 @@ do_connect_wifi(int argc, char **argv) { int option; - wladm_wlan_attr_t attr, *attrp; - wladm_status_t status = WLADM_STATUS_OK; - int timeout = WLADM_CONNECT_TIMEOUT_DEFAULT; + dladm_wlan_attr_t attr, *attrp; + dladm_status_t status = DLADM_STATUS_OK; + int timeout = DLADM_WLAN_CONNECT_TIMEOUT_DEFAULT; const char *link = NULL; - wladm_wep_key_t *keys = NULL; + dladm_wlan_wepkey_t *keys = NULL; uint_t key_count = 0; uint_t flags = 0; - wladm_secmode_t keysecmode = WLADM_SECMODE_NONE; + dladm_wlan_secmode_t keysecmode = DLADM_WLAN_SECMODE_NONE; opterr = 0; (void) memset(&attr, 0, sizeof (attr)); @@ -2140,56 +2097,58 @@ wifi_longopts, NULL)) != -1) { switch (option) { case 'e': - status = wladm_str2essid(optarg, &attr.wa_essid); - if (status != WLADM_STATUS_OK) + status = dladm_wlan_str2essid(optarg, &attr.wa_essid); + if (status != DLADM_STATUS_OK) die("invalid ESSID '%s'", optarg); - attr.wa_valid |= WLADM_WLAN_ATTR_ESSID; + attr.wa_valid |= DLADM_WLAN_ATTR_ESSID; /* * Try to connect without doing a scan. */ - flags |= WLADM_OPT_NOSCAN; + flags |= DLADM_WLAN_CONNECT_NOSCAN; break; case 'i': - status = wladm_str2bssid(optarg, &attr.wa_bssid); - if (status != WLADM_STATUS_OK) + status = dladm_wlan_str2bssid(optarg, &attr.wa_bssid); + if (status != DLADM_STATUS_OK) die("invalid BSSID %s", optarg); - attr.wa_valid |= WLADM_WLAN_ATTR_BSSID; + attr.wa_valid |= DLADM_WLAN_ATTR_BSSID; break; case 'a': - status = wladm_str2auth(optarg, &attr.wa_auth); - if (status != WLADM_STATUS_OK) + status = dladm_wlan_str2auth(optarg, &attr.wa_auth); + if (status != DLADM_STATUS_OK) die("invalid authentication mode '%s'", optarg); - attr.wa_valid |= WLADM_WLAN_ATTR_AUTH; + attr.wa_valid |= DLADM_WLAN_ATTR_AUTH; break; case 'm': - status = wladm_str2mode(optarg, &attr.wa_mode); - if (status != WLADM_STATUS_OK) + status = dladm_wlan_str2mode(optarg, &attr.wa_mode); + if (status != DLADM_STATUS_OK) die("invalid mode '%s'", optarg); - attr.wa_valid |= WLADM_WLAN_ATTR_MODE; + attr.wa_valid |= DLADM_WLAN_ATTR_MODE; break; case 'b': - status = wladm_str2bsstype(optarg, &attr.wa_bsstype); - if (status != WLADM_STATUS_OK) + if ((status = dladm_wlan_str2bsstype(optarg, + &attr.wa_bsstype)) != DLADM_STATUS_OK) { die("invalid bsstype '%s'", optarg); - - attr.wa_valid |= WLADM_WLAN_ATTR_BSSTYPE; + } + + attr.wa_valid |= DLADM_WLAN_ATTR_BSSTYPE; break; case 's': - status = wladm_str2secmode(optarg, &attr.wa_secmode); - if (status != WLADM_STATUS_OK) + if ((status = dladm_wlan_str2secmode(optarg, + &attr.wa_secmode)) != DLADM_STATUS_OK) { die("invalid security mode '%s'", optarg); - - attr.wa_valid |= WLADM_WLAN_ATTR_SECMODE; + } + + attr.wa_valid |= DLADM_WLAN_ATTR_SECMODE; break; case 'k': if (parse_wep_keys(optarg, &keys, &key_count) < 0) die("invalid key(s) '%s'", optarg); - keysecmode = WLADM_SECMODE_WEP; + keysecmode = DLADM_WLAN_SECMODE_WEP; break; case 'T': if (strcasecmp(optarg, "forever") == 0) { @@ -2200,7 +2159,7 @@ die("invalid timeout value '%s'", optarg); break; case 'c': - flags |= WLADM_OPT_CREATEIBSS; + flags |= DLADM_WLAN_CONNECT_CREATEIBSS; break; default: die_opterr(optopt, option); @@ -2208,17 +2167,17 @@ } } - if (keysecmode == WLADM_SECMODE_NONE) { - if ((attr.wa_valid & WLADM_WLAN_ATTR_SECMODE) != 0 && - attr.wa_secmode == WLADM_SECMODE_WEP) + if (keysecmode == DLADM_WLAN_SECMODE_NONE) { + if ((attr.wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0 && + attr.wa_secmode == DLADM_WLAN_SECMODE_WEP) die("key required for security mode 'wep'"); } else { - if ((attr.wa_valid & WLADM_WLAN_ATTR_SECMODE) != 0 && + if ((attr.wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0 && attr.wa_secmode != keysecmode) die("incompatible -s and -k options"); } attr.wa_secmode = keysecmode; - attr.wa_valid |= WLADM_WLAN_ATTR_SECMODE; + attr.wa_valid |= DLADM_WLAN_ATTR_SECMODE; if (optind == (argc - 1)) link = argv[optind]; @@ -2230,7 +2189,7 @@ wcattr.wc_link = NULL; wcattr.wc_count = 0; - (void) wladm_walk(&wcattr, do_count_wlan); + (void) dladm_wlan_walk(&wcattr, do_count_wlan); if (wcattr.wc_count == 0) { die("no wifi links are available"); } else if (wcattr.wc_count > 1) { @@ -2241,17 +2200,17 @@ } attrp = (attr.wa_valid == 0) ? NULL : &attr; again: - status = wladm_connect(link, attrp, timeout, keys, key_count, flags); - if (status != WLADM_STATUS_OK) { - if ((flags & WLADM_OPT_NOSCAN) != 0) { + if ((status = dladm_wlan_connect(link, attrp, timeout, keys, + key_count, flags)) != DLADM_STATUS_OK) { + if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0) { /* * Try again with scanning and filtering. */ - flags &= ~WLADM_OPT_NOSCAN; + flags &= ~DLADM_WLAN_CONNECT_NOSCAN; goto again; } - if (status == WLADM_STATUS_NOTFOUND) { + if (status == DLADM_STATUS_NOTFOUND) { if (attr.wa_valid == 0) { die("no wifi networks are available"); } else { @@ -2259,7 +2218,7 @@ "criteria are available"); } } - die_wlerr(status, "cannot connect link '%s'", link); + die_dlerr(status, "cannot connect link '%s'", link); } free(keys); } @@ -2268,11 +2227,11 @@ static boolean_t do_all_disconnect_wifi(void *arg, const char *link) { - wladm_status_t status; - - status = wladm_disconnect(link); - if (status != WLADM_STATUS_OK) - warn_wlerr(status, "cannot disconnect link '%s'", link); + dladm_status_t status; + + status = dladm_wlan_disconnect(link); + if (status != DLADM_STATUS_OK) + warn_dlerr(status, "cannot disconnect link '%s'", link); return (B_TRUE); } @@ -2283,7 +2242,7 @@ int option; const char *link = NULL; boolean_t all_links = B_FALSE; - wladm_status_t status; + dladm_status_t status; wlan_count_attr_t wcattr; opterr = 0; @@ -2308,7 +2267,7 @@ if (!all_links) { wcattr.wc_link = NULL; wcattr.wc_count = 0; - (void) wladm_walk(&wcattr, do_count_wlan); + (void) dladm_wlan_walk(&wcattr, do_count_wlan); if (wcattr.wc_count == 0) { die("no wifi links are available"); } else if (wcattr.wc_count > 1) { @@ -2317,13 +2276,14 @@ } link = wcattr.wc_link; } else { - (void) wladm_walk(&all_links, do_all_disconnect_wifi); + (void) dladm_wlan_walk(&all_links, + do_all_disconnect_wifi); return; } } - status = wladm_disconnect(link); - if (status != WLADM_STATUS_OK) - die_wlerr(status, "cannot disconnect link '%s'", link); + status = dladm_wlan_disconnect(link); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "cannot disconnect link '%s'", link); } #define MAX_PROPS 32 @@ -2347,9 +2307,11 @@ char *ls_line; char **ls_propvals; prop_list_t *ls_proplist; - boolean_t ls_parseable; - boolean_t ls_persist; - boolean_t ls_header; + uint32_t ls_parseable : 1, + ls_persist : 1, + ls_header : 1, + ls_pad_bits : 29; + dladm_status_t ls_status; } show_linkprop_state_t; static void @@ -2447,15 +2409,22 @@ status = dladm_get_prop(statep->ls_link, type, propname, propvals, &valcnt); if (status != DLADM_STATUS_OK) { - if (status == DLADM_STATUS_NOTSUP || statep->ls_persist) { + if (status == DLADM_STATUS_TEMPONLY) { + statep->ls_status = status; + return; + } else if (status == DLADM_STATUS_NOTSUP || + statep->ls_persist) { valcnt = 1; if (type == DLADM_PROP_VAL_CURRENT) propvals = &unknown; else propvals = ¬sup; } else { - die_dlerr(status, "cannot get link property '%s'", - propname); + statep->ls_status = status; + warn_dlerr(status, + "cannot get link property '%s' for %s", + propname, statep->ls_link); + return; } } @@ -2488,9 +2457,6 @@ char *ptr = statep->ls_line; char *lim = ptr + MAX_PROP_LINE; - if (statep->ls_persist && dladm_is_prop_temponly(propname, NULL)) - return (B_TRUE); - if (statep->ls_parseable) ptr += snprintf(ptr, lim - ptr, "LINK=\"%s\" ", statep->ls_link); @@ -2505,10 +2471,24 @@ print_linkprop(statep, propname, statep->ls_persist ? DLADM_PROP_VAL_PERSISTENT : DLADM_PROP_VAL_CURRENT, "VALUE", "%-14s ", &ptr); + + /* + * If we failed to query the link property, for example, query + * the persistent value of a non-persistable link property, simply + * skip the output. + */ + if (statep->ls_status != DLADM_STATUS_OK) + return (B_TRUE); + print_linkprop(statep, propname, DLADM_PROP_VAL_DEFAULT, "DEFAULT", "%-14s ", &ptr); + if (statep->ls_status != DLADM_STATUS_OK) + return (B_TRUE); + print_linkprop(statep, propname, DLADM_PROP_VAL_MODIFIABLE, "POSSIBLE", "%-20s ", &ptr); + if (statep->ls_status != DLADM_STATUS_OK) + return (B_TRUE); if (statep->ls_header) { statep->ls_header = B_FALSE; @@ -2558,6 +2538,7 @@ usage(); state.ls_proplist = proplist; + state.ls_status = DLADM_STATUS_OK; if (state.ls_link == NULL) { (void) dladm_walk(show_linkprop_onelink, &state); @@ -2565,6 +2546,9 @@ show_linkprop_onelink(&state, state.ls_link); } free_props(proplist); + + if (state.ls_status != DLADM_STATUS_OK) + exit(EXIT_FAILURE); } static void @@ -2590,8 +2574,11 @@ * (below) will proceed slowly unless we hold the link open. */ (void) snprintf(linkname, MAXPATHLEN, "/dev/%s", link); - if ((fd = open(linkname, O_RDWR)) < 0) - die("cannot open %s: %s", link, strerror(errno)); + if ((fd = open(linkname, O_RDWR)) < 0) { + warn("cannot open %s: %s", link, strerror(errno)); + statep->ls_status = DLADM_STATUS_NOTFOUND; + return; + } buf = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * MAX_PROP_VALS + MAX_PROP_LINE); @@ -2607,15 +2594,13 @@ (sizeof (char *) + DLADM_PROP_VAL_MAX) * MAX_PROP_VALS; if (proplist != NULL) { - for (i = 0; i < proplist->pl_count; i++) { - if (!show_linkprop(statep, - proplist->pl_info[i].pi_name)) - break; - } + for (i = 0; i < proplist->pl_count; i++) + (void) show_linkprop(statep, + proplist->pl_info[i].pi_name); } else { status = dladm_walk_prop(link, statep, show_linkprop); if (status != DLADM_STATUS_OK) - die_dlerr(status, "show-linkprop"); + warn_dlerr(status, "show-linkprop failed for %s", link); } (void) close(fd); free(buf); @@ -3354,22 +3339,6 @@ /* PRINTFLIKE2 */ static void -warn_wlerr(wladm_status_t err, const char *format, ...) -{ - va_list alist; - char errmsg[WLADM_STRSIZE]; - - format = gettext(format); - (void) fprintf(stderr, gettext("%s: warning: "), progname); - - va_start(alist, format); - (void) vfprintf(stderr, format, alist); - va_end(alist); - (void) fprintf(stderr, ": %s\n", wladm_status2str(err, errmsg)); -} - -/* PRINTFLIKE2 */ -static void warn_dlerr(dladm_status_t err, const char *format, ...) { va_list alist; @@ -3386,46 +3355,6 @@ /* PRINTFLIKE2 */ static void -die_laerr(laadm_diag_t diag, const char *format, ...) -{ - va_list alist; - char *errstr = strerror(errno); - - format = gettext(format); - (void) fprintf(stderr, "%s: ", progname); - - va_start(alist, format); - (void) vfprintf(stderr, format, alist); - va_end(alist); - - if (diag == 0) - (void) fprintf(stderr, ": %s\n", errstr); - else - (void) fprintf(stderr, ": %s (%s)\n", errstr, laadm_diag(diag)); - - exit(EXIT_FAILURE); -} - -/* PRINTFLIKE2 */ -static void -die_wlerr(wladm_status_t err, const char *format, ...) -{ - va_list alist; - char errmsg[WLADM_STRSIZE]; - - format = gettext(format); - (void) fprintf(stderr, "%s: ", progname); - - va_start(alist, format); - (void) vfprintf(stderr, format, alist); - va_end(alist); - (void) fprintf(stderr, ": %s\n", wladm_status2str(err, errmsg)); - - exit(EXIT_FAILURE); -} - -/* PRINTFLIKE2 */ -static void die_dlerr(dladm_status_t err, const char *format, ...) { va_list alist; diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/cmd/rcm_daemon/Makefile.com --- a/usr/src/cmd/rcm_daemon/Makefile.com Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/cmd/rcm_daemon/Makefile.com Wed Mar 21 09:48:58 2007 -0700 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -106,7 +106,7 @@ LDLIBS_MODULES = SUNW_pool_rcm.so := LDLIBS_MODULES += -L$(ROOT)/usr/lib -lpool SUNW_svm_rcm.so := LDLIBS_MODULES += -L$(ROOT)/usr/lib -lmeta -SUNW_network_rcm.so := LDLIBS_MODULES += -L$(ROOT)/lib -llaadm +SUNW_network_rcm.so := LDLIBS_MODULES += -L$(ROOT)/lib -ldladm SUNW_ip_rcm.so := LDLIBS_MODULES += -L$(ROOT)/lib -linetutil SUNW_ip_anon_rcm.so := LDLIBS_MODULES += -L$(ROOT)/lib -linetutil diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/cmd/rcm_daemon/common/network_rcm.c --- a/usr/src/cmd/rcm_daemon/common/network_rcm.c Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/cmd/rcm_daemon/common/network_rcm.c Wed Mar 21 09:48:58 2007 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include "rcm_module.h" /* @@ -751,10 +751,10 @@ } aggr_walker_state_t; static int -aggr_walker(void *arg, laadm_grp_attr_sys_t *grp) +aggr_walker(void *arg, dladm_aggr_grp_attr_t *grp) { aggr_walker_state_t *state = arg; - laadm_port_attr_sys_t *port; + dladm_aggr_port_attr_t *port; int i; for (i = 0; i < grp->lg_nports; i++) { @@ -782,7 +782,7 @@ (void) snprintf(state.dev_name, sizeof (state.dev_name), "%s%d", driver, ppa); - if (laadm_walk_sys(aggr_walker, &state) != 0) { + if (dladm_aggr_walk(aggr_walker, &state) != 0) { rcm_log_message(RCM_ERROR, gettext("NET: cannot walk " "aggregations (%s)\n"), strerror(errno)); return (B_FALSE); diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/cmd/zoneadmd/vplat.c --- a/usr/src/cmd/zoneadmd/vplat.c Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/cmd/zoneadmd/vplat.c Wed Mar 21 09:48:58 2007 -0700 @@ -76,7 +76,7 @@ #include #include -#include +#include #include #include diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/Makefile --- a/usr/src/lib/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/lib/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -112,9 +112,7 @@ libkmf \ libkstat \ libkvm \ - liblaadm \ liblm \ - libmacadm \ libmalloc \ libmapmalloc \ libmtmalloc \ @@ -185,7 +183,6 @@ madv \ mpss \ libdisasm \ - libwladm \ libwrap \ libxcurses \ libxcurses2 \ @@ -295,7 +292,6 @@ libuutil \ libwanboot \ libwanbootutil \ - libwladm \ libzfs \ libzonecfg \ lvm \ @@ -350,8 +346,6 @@ libiscsitgt \ libkstat \ libkvm \ - liblaadm \ - libmacadm \ libmail \ libmd \ libmtmalloc \ @@ -386,7 +380,6 @@ libvolmgt \ libumem \ libuutil \ - libwladm \ libwrap \ libxcurses2 \ libzfs \ @@ -475,8 +468,8 @@ libdhcpagent: libsocket libdhcputil libuuid libdlpi libdhcpsvc: libinetutil libdhcputil: libnsl libgen libinetutil libdlpi +libdladm: libdlpi libdevinfo libinetutil libsocket libdlpi: libinetutil -libdladm: libdlpi libdevinfo libwladm libinetutil libdtrace: libproc libgen libctf libdtrace_jni: libuutil libdtrace libefi: libuuid @@ -487,7 +480,6 @@ libkmf: libcryptoutil pkcs11 openssl libnsl: libmd5 libscf libmapid: libresolv -libmacadm: libdevinfo libuuid: libsocket libinetutil: libsocket libsecdb: libnsl @@ -508,7 +500,6 @@ libwanboot: libnvpair libresolv libnsl libsocket libdevinfo libinetutil \ libdhcputil openssl libwanbootutil: libnsl -libwladm: libdevinfo libsocket pam_modules: libproject passwdutil $(SMARTCARD) libscf: libuutil libmd libinetsvc: libscf diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/Makefile --- a/usr/src/lib/libdladm/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/lib/libdladm/Makefile Wed Mar 21 09:48:58 2007 -0700 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -27,13 +27,15 @@ include $(SRC)/lib/Makefile.lib -HDRS = libdladm.h libdladm_impl.h +HDRS = libdladm.h libdladm_impl.h libdllink.h libdlaggr.h \ + libdlwlan.h libdlwlan_impl.h HDRDIR = common SUBDIRS = $(MACH) POFILE = libdladm.po -MSGFILES = common/libdladm.c common/linkprop.c common/secobj.c +MSGFILES = common/libdladm.c common/linkprop.c common/secobj.c \ + common/libdllink.c comon/libdlaggr.c common/libdlwlan.c XGETFLAGS = -a -x libdladm.xcl all := TARGET = all diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/Makefile.com --- a/usr/src/lib/libdladm/Makefile.com Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/lib/libdladm/Makefile.com Wed Mar 21 09:48:58 2007 -0700 @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -27,7 +27,7 @@ LIBRARY = libdladm.a VERS = .1 -OBJECTS = libdladm.o secobj.o linkprop.o +OBJECTS = libdladm.o secobj.o linkprop.o libdllink.o libdlaggr.o libdlwlan.o include ../../Makefile.lib @@ -35,7 +35,7 @@ include ../../Makefile.rootfs LIBS = $(DYNLIB) $(LINTLIB) -LDLIBS += -ldevinfo -ldlpi -lc -lwladm -linetutil +LDLIBS += -ldevinfo -ldlpi -lc -linetutil -lsocket SRCDIR = ../common $(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/libdladm.c --- a/usr/src/lib/libdladm/common/libdladm.c Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/lib/libdladm/common/libdladm.c Wed Mar 21 09:48:58 2007 -0700 @@ -25,30 +25,16 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#include #include #include #include #include #include #include -#include #include -#include -#include -#include +#include #include #include -#include - -typedef struct dladm_dev { - char dd_name[IFNAMSIZ]; - struct dladm_dev *dd_next; -} dladm_dev_t; - -typedef struct dladm_walk { - dladm_dev_t *dw_dev_list; -} dladm_walk_t; static char dladm_rootdir[MAXPATHLEN] = "/"; @@ -69,239 +55,6 @@ return (ioctl(fd, I_STR, &iocb)); } -/* - * Return the attributes of the specified datalink from the DLD driver. - */ -static int -i_dladm_info(int fd, const char *name, dladm_attr_t *dap) -{ - dld_ioc_attr_t dia; - - if (strlen(name) >= IFNAMSIZ) { - errno = EINVAL; - return (-1); - } - - (void) strlcpy(dia.dia_name, name, IFNAMSIZ); - - if (i_dladm_ioctl(fd, DLDIOCATTR, &dia, sizeof (dia)) < 0) - return (-1); - - (void) strlcpy(dap->da_dev, dia.dia_dev, MAXNAMELEN); - dap->da_max_sdu = dia.dia_max_sdu; - dap->da_vid = dia.dia_vid; - - return (0); -} - -/* - * Adds a datalink to the array corresponding to arg. - */ -static void -i_dladm_nt_net_add(void *arg, char *name) -{ - dladm_walk_t *dwp = arg; - dladm_dev_t *ddp = dwp->dw_dev_list; - dladm_dev_t **lastp = &dwp->dw_dev_list; - - while (ddp) { - /* - * Skip duplicates. - */ - if (strcmp(ddp->dd_name, name) == 0) - return; - - lastp = &ddp->dd_next; - ddp = ddp->dd_next; - } - - if ((ddp = malloc(sizeof (*ddp))) == NULL) - return; - - (void) strlcpy(ddp->dd_name, name, IFNAMSIZ); - ddp->dd_next = NULL; - *lastp = ddp; -} - -/* - * Walker callback invoked for each DDI_NT_NET node. - */ -static int -i_dladm_nt_net_walk(di_node_t node, di_minor_t minor, void *arg) -{ - char linkname[DLPI_LINKNAME_MAX]; - dlpi_handle_t dh; - - if (dlpi_makelink(linkname, di_minor_name(minor), - di_instance(node)) != DLPI_SUCCESS) - return (DI_WALK_CONTINUE); - - if (dlpi_open(linkname, &dh, 0) == DLPI_SUCCESS) { - i_dladm_nt_net_add(arg, linkname); - dlpi_close(dh); - } - return (DI_WALK_CONTINUE); -} - -/* - * Hold a data-link. - */ -static int -i_dladm_hold_link(const char *name, zoneid_t zoneid, boolean_t docheck) -{ - int fd; - dld_hold_vlan_t dhv; - - if (strlen(name) >= IFNAMSIZ) { - errno = EINVAL; - return (-1); - } - - if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) - return (-1); - - bzero(&dhv, sizeof (dld_hold_vlan_t)); - (void) strlcpy(dhv.dhv_name, name, IFNAMSIZ); - dhv.dhv_zid = zoneid; - dhv.dhv_docheck = docheck; - - if (i_dladm_ioctl(fd, DLDIOCHOLDVLAN, &dhv, sizeof (dhv)) < 0) { - int olderrno = errno; - - (void) close(fd); - errno = olderrno; - return (-1); - } - - (void) close(fd); - return (0); -} - -/* - * Release a data-link. - */ -static int -i_dladm_rele_link(const char *name, zoneid_t zoneid, boolean_t docheck) -{ - int fd; - dld_hold_vlan_t dhv; - - if (strlen(name) >= IFNAMSIZ) { - errno = EINVAL; - return (-1); - } - - if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) - return (-1); - - bzero(&dhv, sizeof (dld_hold_vlan_t)); - (void) strlcpy(dhv.dhv_name, name, IFNAMSIZ); - dhv.dhv_zid = zoneid; - dhv.dhv_docheck = docheck; - - if (i_dladm_ioctl(fd, DLDIOCRELEVLAN, &dhv, sizeof (dhv)) < 0) { - int olderrno = errno; - - (void) close(fd); - errno = olderrno; - return (-1); - } - - (void) close(fd); - return (0); -} - -/* - * Invoke the specified callback function for each active DDI_NT_NET - * node. - */ -int -dladm_walk(void (*fn)(void *, const char *), void *arg) -{ - di_node_t root; - dladm_walk_t dw; - dladm_dev_t *ddp, *last_ddp; - - if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) { - errno = EFAULT; - return (-1); - } - dw.dw_dev_list = NULL; - - (void) di_walk_minor(root, DDI_NT_NET, DI_CHECK_ALIAS, &dw, - i_dladm_nt_net_walk); - - di_fini(root); - - ddp = dw.dw_dev_list; - while (ddp) { - fn(arg, ddp->dd_name); - last_ddp = ddp; - ddp = ddp->dd_next; - free(last_ddp); - } - - return (0); -} - -/* - * Invoke the specified callback function for each vlan managed by dld - */ -int -dladm_walk_vlan(void (*fn)(void *, const char *), void *arg, const char *name) -{ - int fd, bufsize, i; - int nvlan = 4094; - dld_ioc_vlan_t *iocp = NULL; - dld_vlan_info_t *dvip; - - if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) - return (-1); - - bufsize = sizeof (dld_ioc_vlan_t) + nvlan * sizeof (dld_vlan_info_t); - - if ((iocp = (dld_ioc_vlan_t *)calloc(1, bufsize)) == NULL) - return (-1); - - (void) strlcpy((char *)iocp->div_name, name, IFNAMSIZ); - if (i_dladm_ioctl(fd, DLDIOCVLAN, iocp, bufsize) == 0) { - dvip = (dld_vlan_info_t *)(iocp + 1); - for (i = 0; i < iocp->div_count; i++) - (*fn)(arg, dvip[i].dvi_name); - } - /* - * Note: Callers of dladm_walk_vlan() ignore the return - * value of this routine. So ignoring ioctl failure case - * and just returning 0. - */ - free(iocp); - (void) close(fd); - return (0); -} - - -/* - * Returns the current attributes of the specified datalink. - */ -int -dladm_info(const char *name, dladm_attr_t *dap) -{ - int fd; - - if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) - return (-1); - - if (i_dladm_info(fd, name, dap) < 0) - goto failed; - - (void) close(fd); - return (0); - -failed: - (void) close(fd); - return (-1); -} - const char * dladm_status2str(dladm_status_t status, char *buf) { @@ -356,6 +109,24 @@ case DLADM_STATUS_TEMPONLY: s = "change cannot be persistent, specify -t please"; break; + case DLADM_STATUS_TIMEDOUT: + s = "operation timed out"; + break; + case DLADM_STATUS_ISCONN: + s = "already connected"; + break; + case DLADM_STATUS_NOTCONN: + s = "not connected"; + break; + case DLADM_STATUS_REPOSITORYINVAL: + s = "invalid configuration repository"; + break; + case DLADM_STATUS_MACADDRINVAL: + s = "invalid MAC address"; + break; + case DLADM_STATUS_KEYINVAL: + s = "invalid key"; + break; default: s = ""; break; @@ -558,21 +329,3 @@ (void) closedir(dp); return (DLADM_STATUS_OK); } - -/* - * Do a "hold" operation to a link. - */ -int -dladm_hold_link(const char *name, zoneid_t zoneid, boolean_t docheck) -{ - return (i_dladm_hold_link(name, zoneid, docheck)); -} - -/* - * Do a "release" operation to a link. - */ -int -dladm_rele_link(const char *name, zoneid_t zoneid, boolean_t docheck) -{ - return (i_dladm_rele_link(name, zoneid, docheck)); -} diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/libdladm.h --- a/usr/src/lib/libdladm/common/libdladm.h Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/lib/libdladm/common/libdladm.h Wed Mar 21 09:48:58 2007 -0700 @@ -28,23 +28,17 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#include -#include -#include +/* + * This file includes structures, macros and common routines shared by all + * data-link administration, and routines which do not directly administrate + * links. For example, dladm_status2str(). + */ #ifdef __cplusplus extern "C" { #endif -typedef struct dladm_attr { - char da_dev[MAXNAMELEN]; - uint_t da_max_sdu; - uint16_t da_vid; -} dladm_attr_t; - #define DLADM_STRSIZE 256 -#define DLADM_SECOBJ_VAL_MAX 256 -#define DLADM_PROP_VAL_MAX 256 #define DLADM_OPT_TEMP 0x00000001 #define DLADM_OPT_CREATE 0x00000002 #define DLADM_OPT_PERSIST 0x00000004 @@ -65,7 +59,13 @@ DLADM_STATUS_DBNOTFOUND, DLADM_STATUS_DENIED, DLADM_STATUS_IOERR, - DLADM_STATUS_TEMPONLY + DLADM_STATUS_TEMPONLY, + DLADM_STATUS_TIMEDOUT, + DLADM_STATUS_ISCONN, + DLADM_STATUS_NOTCONN, + DLADM_STATUS_REPOSITORYINVAL, + DLADM_STATUS_MACADDRINVAL, + DLADM_STATUS_KEYINVAL } dladm_status_t; typedef enum { @@ -75,41 +75,8 @@ DLADM_PROP_VAL_PERSISTENT } dladm_prop_type_t; -#define DLADM_SECOBJ_CLASS_WEP 0 -typedef int dladm_secobj_class_t; - -typedef void (dladm_walkcb_t)(void *, const char *); - -extern int dladm_walk(dladm_walkcb_t *, void *); -extern int dladm_walk_vlan(dladm_walkcb_t *, void *, const char *); -extern int dladm_info(const char *, dladm_attr_t *); -extern int dladm_hold_link(const char *, zoneid_t, boolean_t); -extern int dladm_rele_link(const char *, zoneid_t, boolean_t); - -extern dladm_status_t dladm_set_prop(const char *, const char *, - char **, uint_t, uint_t, char **); -extern dladm_status_t dladm_get_prop(const char *, dladm_prop_type_t, - const char *, char **, uint_t *); -extern dladm_status_t dladm_walk_prop(const char *, void *, - boolean_t (*)(void *, const char *)); -extern boolean_t dladm_is_prop_temponly(const char *, char **); - -extern dladm_status_t dladm_set_secobj(const char *, dladm_secobj_class_t, - uint8_t *, uint_t, uint_t); -extern dladm_status_t dladm_get_secobj(const char *, dladm_secobj_class_t *, - uint8_t *, uint_t *, uint_t); -extern dladm_status_t dladm_unset_secobj(const char *, uint_t); -extern dladm_status_t dladm_walk_secobj(void *, - boolean_t (*)(void *, const char *), uint_t); - extern const char *dladm_status2str(dladm_status_t, char *); -extern const char *dladm_secobjclass2str(dladm_secobj_class_t, char *); -extern dladm_status_t dladm_str2secobjclass(const char *, - dladm_secobj_class_t *); - -extern dladm_status_t dladm_init_linkprop(void); -extern dladm_status_t dladm_init_secobj(void); -extern dladm_status_t dladm_set_rootdir(const char *rootdir); +extern dladm_status_t dladm_set_rootdir(const char *); #ifdef __cplusplus } diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/libdlaggr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libdladm/common/libdlaggr.c Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,1725 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Link Aggregation Administration Library. + * + * This library is used by administration tools such as dladm(1M) to + * configure link aggregations. + * + * Link aggregation configuration information is saved in a text + * file of the following format: + * + * ::= * + * ::= + * + * ::= ' ' | '\t' + * ::= + * ::= + * ::= * + * ::= ',' + * ::= + * ::= + * ::= + * ::= * + * ::= ',' + * ::= 'L2' | 'L3' | 'L4' + * ::= 'auto' | + * ::= ':' ':' ':' ':' ':' + * ::= 'off' | 'active' | 'passive' + * ::= 'short' | 'long' + */ + +#define DLADM_AGGR_DEV "/devices/pseudo/aggr@0:" AGGR_DEVNAME_CTL +#define DLADM_AGGR_DB "/etc/dladm/aggregation.conf" +#define DLADM_AGGR_DB_TMP "/etc/dladm/aggregation.conf.new" +#define DLADM_AGGR_DB_LOCK "/tmp/aggregation.conf.lock" + +#define DLADM_AGGR_DB_PERMS S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH +#define DLADM_AGGR_DB_OWNER 15 /* "dladm" UID */ +#define DLADM_AGGR_DB_GROUP 3 /* "sys" GID */ + +/* + * The largest configurable aggregation key. Because by default the key is + * used as the DLPI device PPA and default VLAN PPA's are calculated as + * ((1000 * vid) + PPA), the largest key can't be > 999. + */ +#define DLADM_AGGR_MAX_KEY 999 + +#define BLANK_LINE(s) ((s[0] == '\0') || (s[0] == '#') || (s[0] == '\n')) + +/* Limits on buffer size for LAIOC_INFO request */ +#define MIN_INFO_SIZE (4*1024) +#define MAX_INFO_SIZE (128*1024) + +#define MAXPATHLEN 1024 + +static uchar_t zero_mac[] = {0, 0, 0, 0, 0, 0}; + +/* configuration database entry */ +typedef struct dladm_aggr_grp_attr_db { + uint32_t lt_key; + uint32_t lt_policy; + uint32_t lt_nports; + dladm_aggr_port_attr_db_t *lt_ports; + boolean_t lt_mac_fixed; + uchar_t lt_mac[ETHERADDRL]; + aggr_lacp_mode_t lt_lacp_mode; + aggr_lacp_timer_t lt_lacp_timer; +} dladm_aggr_grp_attr_db_t; + +typedef struct dladm_aggr_up { + uint32_t lu_key; + boolean_t lu_found; + int lu_fd; +} dladm_aggr_up_t; + +typedef struct dladm_aggr_down { + uint32_t ld_key; + boolean_t ld_found; +} dladm_aggr_down_t; + +typedef struct dladm_aggr_modify_attr { + uint32_t ld_policy; + boolean_t ld_mac_fixed; + uchar_t ld_mac[ETHERADDRL]; + aggr_lacp_mode_t ld_lacp_mode; + aggr_lacp_timer_t ld_lacp_timer; +} dladm_aggr_modify_attr_t; + +typedef struct policy_s { + char *pol_name; + uint32_t policy; +} policy_t; + +static policy_t policies[] = { + {"L2", AGGR_POLICY_L2}, + {"L3", AGGR_POLICY_L3}, + {"L4", AGGR_POLICY_L4}}; + +#define NPOLICIES (sizeof (policies) / sizeof (policy_t)) + +typedef struct dladm_aggr_lacpmode_s { + char *mode_str; + aggr_lacp_mode_t mode_id; +} dladm_aggr_lacpmode_t; + +static dladm_aggr_lacpmode_t lacp_modes[] = { + {"off", AGGR_LACP_OFF}, + {"active", AGGR_LACP_ACTIVE}, + {"passive", AGGR_LACP_PASSIVE}}; + +#define NLACP_MODES (sizeof (lacp_modes) / sizeof (dladm_aggr_lacpmode_t)) + +typedef struct dladm_aggr_lacptimer_s { + char *lt_str; + aggr_lacp_timer_t lt_id; +} dladm_aggr_lacptimer_t; + +static dladm_aggr_lacptimer_t lacp_timers[] = { + {"short", AGGR_LACP_TIMER_SHORT}, + {"long", AGGR_LACP_TIMER_LONG}}; + +#define NLACP_TIMERS (sizeof (lacp_timers) / sizeof (dladm_aggr_lacptimer_t)) + +typedef struct dladm_aggr_port_state { + char *state_str; + aggr_port_state_t state_id; +} dladm_aggr_port_state_t; + +static dladm_aggr_port_state_t port_states[] = { + {"standby", AGGR_PORT_STATE_STANDBY }, + {"attached", AGGR_PORT_STATE_ATTACHED } +}; + +#define NPORT_STATES \ + (sizeof (port_states) / sizeof (dladm_aggr_port_state_t)) + +typedef struct delete_db_state { + uint32_t ds_key; + boolean_t ds_found; +} delete_db_state_t; + +typedef struct modify_db_state { + uint32_t us_key; + uint32_t us_mask; + dladm_aggr_modify_attr_t *us_attr_new; + dladm_aggr_modify_attr_t *us_attr_old; + boolean_t us_found; +} modify_db_state_t; + +typedef struct add_db_state { + dladm_aggr_grp_attr_db_t *as_attr; + boolean_t as_found; +} add_db_state_t; + +static int i_dladm_aggr_fput_grp(FILE *, dladm_aggr_grp_attr_db_t *); + +static int +i_dladm_aggr_strioctl(int fd, int cmd, void *ptr, int ilen) +{ + struct strioctl str; + + str.ic_cmd = cmd; + str.ic_timout = 0; + str.ic_len = ilen; + str.ic_dp = ptr; + + return (ioctl(fd, I_STR, &str)); +} + +/* + * Open and lock the aggregation configuration file lock. The lock is + * acquired as a reader (F_RDLCK) or writer (F_WRLCK). + */ +static int +i_dladm_aggr_lock_db(short type) +{ + int lock_fd; + struct flock lock; + int errno_save; + + if ((lock_fd = open(DLADM_AGGR_DB_LOCK, O_RDWR | O_CREAT | O_TRUNC, + DLADM_AGGR_DB_PERMS)) < 0) + return (-1); + + lock.l_type = type; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + + if (fcntl(lock_fd, F_SETLKW, &lock) < 0) { + errno_save = errno; + (void) close(lock_fd); + (void) unlink(DLADM_AGGR_DB_LOCK); + errno = errno_save; + return (-1); + } + return (lock_fd); +} + +/* + * Unlock and close the specified file. + */ +static void +i_dladm_aggr_unlock_db(int fd) +{ + struct flock lock; + + if (fd < 0) + return; + + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + + (void) fcntl(fd, F_SETLKW, &lock); + (void) close(fd); + (void) unlink(DLADM_AGGR_DB_LOCK); +} + +/* + * Walk through the groups defined on the system and for each group , + * invoke (, ); + * Terminate the walk if at any time returns non-NULL value + */ +int +dladm_aggr_walk(int (*fn)(void *, dladm_aggr_grp_attr_t *), void *arg) +{ + laioc_info_t *ioc; + laioc_info_group_t *grp; + laioc_info_port_t *port; + dladm_aggr_grp_attr_t attr; + int rc, i, j, bufsize, fd; + char *where; + + if ((fd = open(DLADM_AGGR_DEV, O_RDWR)) == -1) + return (-1); + + bufsize = MIN_INFO_SIZE; + ioc = (laioc_info_t *)calloc(1, bufsize); + if (ioc == NULL) { + (void) close(fd); + errno = ENOMEM; + return (-1); + } + +tryagain: + rc = i_dladm_aggr_strioctl(fd, LAIOC_INFO, ioc, bufsize); + + if (rc != 0) { + if (errno == ENOSPC) { + /* + * The LAIOC_INFO call failed due to a short + * buffer. Reallocate the buffer and try again. + */ + bufsize *= 2; + if (bufsize <= MAX_INFO_SIZE) { + ioc = (laioc_info_t *)realloc(ioc, bufsize); + if (ioc != NULL) { + bzero(ioc, sizeof (bufsize)); + goto tryagain; + } + } + } + goto bail; + } + + /* + * Go through each group returned by the aggregation driver. + */ + where = (char *)(ioc + 1); + for (i = 0; i < ioc->li_ngroups; i++) { + /* LINTED E_BAD_PTR_CAST_ALIGN */ + grp = (laioc_info_group_t *)where; + + attr.lg_key = grp->lg_key; + attr.lg_nports = grp->lg_nports; + attr.lg_policy = grp->lg_policy; + attr.lg_lacp_mode = grp->lg_lacp_mode; + attr.lg_lacp_timer = grp->lg_lacp_timer; + + bcopy(grp->lg_mac, attr.lg_mac, ETHERADDRL); + attr.lg_mac_fixed = grp->lg_mac_fixed; + + attr.lg_ports = malloc(grp->lg_nports * + sizeof (dladm_aggr_port_attr_t)); + if (attr.lg_ports == NULL) { + errno = ENOMEM; + goto bail; + } + + where = (char *)(grp + 1); + + /* + * Go through each port that is part of the group. + */ + for (j = 0; j < grp->lg_nports; j++) { + /* LINTED E_BAD_PTR_CAST_ALIGN */ + port = (laioc_info_port_t *)where; + + bcopy(port->lp_devname, attr.lg_ports[j].lp_devname, + MAXNAMELEN + 1); + bcopy(port->lp_mac, attr.lg_ports[j].lp_mac, + ETHERADDRL); + attr.lg_ports[j].lp_state = port->lp_state; + attr.lg_ports[j].lp_lacp_state = port->lp_lacp_state; + + where = (char *)(port + 1); + } + + rc = fn(arg, &attr); + free(attr.lg_ports); + if (rc != 0) + goto bail; + } + +bail: + free(ioc); + (void) close(fd); + return (rc); +} + +/* + * Parse one line of the link aggregation DB, and return the corresponding + * group. Memory for the ports associated with the aggregation may be + * allocated. It is the responsibility of the caller to free the lt_ports + * aggregation group attribute. + * + * Returns -1 on parsing failure, or 0 on success. + */ +static int +i_dladm_aggr_parse_db(char *line, dladm_aggr_grp_attr_db_t *attr) +{ + char *token; + int i; + int value; + char *endp = NULL; + char *lasts = NULL; + + bzero(attr, sizeof (*attr)); + + /* key */ + if ((token = strtok_r(line, " \t", &lasts)) == NULL) + goto failed; + + errno = 0; + value = (int)strtol(token, &endp, 10); + if (errno != 0 || *endp != '\0') + goto failed; + + attr->lt_key = value; + + /* policy */ + if ((token = strtok_r(NULL, " \t", &lasts)) == NULL || + !dladm_aggr_str2policy(token, &attr->lt_policy)) + goto failed; + + /* number of ports */ + if ((token = strtok_r(NULL, " \t", &lasts)) == NULL) + return (-1); + + errno = 0; + value = (int)strtol(token, &endp, 10); + if (errno != 0 || *endp != '\0') + goto failed; + + attr->lt_nports = value; + + /* ports */ + if ((attr->lt_ports = malloc(attr->lt_nports * + sizeof (dladm_aggr_port_attr_db_t))) == NULL) + goto failed; + + for (i = 0; i < attr->lt_nports; i++) { + char *where, *devname; + + /* port */ + if ((token = strtok_r(NULL, ", \t\n", &lasts)) == NULL) + goto failed; + + /* + * device name: In a previous version of this file, a port + * number could be specified using /. + * This syntax is unecessary and obsolete. + */ + if ((devname = strtok_r(token, "/", &where)) == NULL) + goto failed; + if (strlcpy(attr->lt_ports[i].lp_devname, devname, + MAXNAMELEN) >= MAXNAMELEN) + goto failed; + } + + /* unicast MAC address */ + if ((token = strtok_r(NULL, " \t\n", &lasts)) == NULL || + !dladm_aggr_str2macaddr(token, &attr->lt_mac_fixed, + attr->lt_mac)) + goto failed; + + /* LACP mode */ + if ((token = strtok_r(NULL, " \t\n", &lasts)) == NULL || + !dladm_aggr_str2lacpmode(token, &attr->lt_lacp_mode)) + attr->lt_lacp_mode = AGGR_LACP_OFF; + + /* LACP timer */ + if ((token = strtok_r(NULL, " \t\n", &lasts)) == NULL || + !dladm_aggr_str2lacptimer(token, &attr->lt_lacp_timer)) + attr->lt_lacp_timer = AGGR_LACP_TIMER_SHORT; + + return (0); + +failed: + free(attr->lt_ports); + attr->lt_ports = NULL; + return (-1); +} + +/* + * Walk through the groups defined in the DB and for each group , + * invoke (, ); + */ +static dladm_status_t +i_dladm_aggr_walk_db(dladm_status_t (*fn)(void *, dladm_aggr_grp_attr_db_t *), + void *arg, const char *root) +{ + FILE *fp; + char line[MAXLINELEN]; + dladm_aggr_grp_attr_db_t attr; + char *db_file; + char db_file_buf[MAXPATHLEN]; + int lock_fd; + dladm_status_t status = DLADM_STATUS_OK; + + if (root == NULL) { + db_file = DLADM_AGGR_DB; + } else { + (void) snprintf(db_file_buf, MAXPATHLEN, "%s%s", root, + DLADM_AGGR_DB); + db_file = db_file_buf; + } + + lock_fd = i_dladm_aggr_lock_db(F_RDLCK); + + if ((fp = fopen(db_file, "r")) == NULL) { + status = dladm_errno2status(errno); + i_dladm_aggr_unlock_db(lock_fd); + return (status); + } + + bzero(&attr, sizeof (attr)); + + while (fgets(line, MAXLINELEN, fp) != NULL) { + /* skip comments */ + if (BLANK_LINE(line)) + continue; + + if (i_dladm_aggr_parse_db(line, &attr) != 0) { + status = DLADM_STATUS_REPOSITORYINVAL; + goto done; + } + + if ((status = fn(arg, &attr)) != DLADM_STATUS_OK) + goto done; + + free(attr.lt_ports); + attr.lt_ports = NULL; + } + +done: + free(attr.lt_ports); + (void) fclose(fp); + i_dladm_aggr_unlock_db(lock_fd); + return (status); +} + +/* + * Send an add or remove command to the link aggregation driver. + */ +static dladm_status_t +i_dladm_aggr_add_rem_sys(dladm_aggr_grp_attr_db_t *attr, int cmd) +{ + int i, rc, fd, len; + laioc_add_rem_t *iocp; + laioc_port_t *ports; + dladm_status_t status = DLADM_STATUS_OK; + + len = sizeof (*iocp) + attr->lt_nports * sizeof (laioc_port_t); + iocp = malloc(len); + if (iocp == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + iocp->la_key = attr->lt_key; + iocp->la_nports = attr->lt_nports; + ports = (laioc_port_t *)(iocp + 1); + + for (i = 0; i < attr->lt_nports; i++) { + if (strlcpy(ports[i].lp_devname, + attr->lt_ports[i].lp_devname, + MAXNAMELEN) >= MAXNAMELEN) { + status = DLADM_STATUS_BADARG; + goto done; + } + } + + if ((fd = open(DLADM_AGGR_DEV, O_RDWR)) < 0) { + status = dladm_errno2status(errno); + goto done; + } + + rc = i_dladm_aggr_strioctl(fd, cmd, iocp, len); + if (rc < 0) { + if (errno == EINVAL) + status = DLADM_STATUS_LINKINVAL; + else + status = dladm_errno2status(errno); + } + + (void) close(fd); + +done: + free(iocp); + return (status); +} + +/* + * Send a modify command to the link aggregation driver. + */ +static dladm_status_t +i_dladm_aggr_modify_sys(uint32_t key, uint32_t mask, + dladm_aggr_modify_attr_t *attr) +{ + int rc, fd; + laioc_modify_t ioc; + dladm_status_t status = DLADM_STATUS_OK; + + ioc.lu_key = key; + + ioc.lu_modify_mask = 0; + if (mask & DLADM_AGGR_MODIFY_POLICY) + ioc.lu_modify_mask |= LAIOC_MODIFY_POLICY; + if (mask & DLADM_AGGR_MODIFY_MAC) + ioc.lu_modify_mask |= LAIOC_MODIFY_MAC; + if (mask & DLADM_AGGR_MODIFY_LACP_MODE) + ioc.lu_modify_mask |= LAIOC_MODIFY_LACP_MODE; + if (mask & DLADM_AGGR_MODIFY_LACP_TIMER) + ioc.lu_modify_mask |= LAIOC_MODIFY_LACP_TIMER; + + ioc.lu_policy = attr->ld_policy; + ioc.lu_mac_fixed = attr->ld_mac_fixed; + bcopy(attr->ld_mac, ioc.lu_mac, ETHERADDRL); + ioc.lu_lacp_mode = attr->ld_lacp_mode; + ioc.lu_lacp_timer = attr->ld_lacp_timer; + + if ((fd = open(DLADM_AGGR_DEV, O_RDWR)) < 0) + return (dladm_errno2status(errno)); + + rc = i_dladm_aggr_strioctl(fd, LAIOC_MODIFY, &ioc, sizeof (ioc)); + if (rc < 0) { + if (errno == EINVAL) + status = DLADM_STATUS_MACADDRINVAL; + else + status = dladm_errno2status(errno); + } + + (void) close(fd); + return (status); +} + +/* + * Send a create command to the link aggregation driver. + */ +static dladm_status_t +i_dladm_aggr_create_sys(int fd, dladm_aggr_grp_attr_db_t *attr) +{ + int i, rc, len; + laioc_create_t *iocp; + laioc_port_t *ports; + dladm_status_t status = DLADM_STATUS_OK; + + len = sizeof (*iocp) + attr->lt_nports * sizeof (laioc_port_t); + iocp = malloc(len); + if (iocp == NULL) + return (DLADM_STATUS_NOMEM); + + iocp->lc_key = attr->lt_key; + iocp->lc_nports = attr->lt_nports; + iocp->lc_policy = attr->lt_policy; + iocp->lc_lacp_mode = attr->lt_lacp_mode; + iocp->lc_lacp_timer = attr->lt_lacp_timer; + + ports = (laioc_port_t *)(iocp + 1); + + for (i = 0; i < attr->lt_nports; i++) { + if (strlcpy(ports[i].lp_devname, + attr->lt_ports[i].lp_devname, + MAXNAMELEN) >= MAXNAMELEN) { + free(iocp); + return (DLADM_STATUS_BADARG); + } + } + + if (attr->lt_mac_fixed && + ((bcmp(zero_mac, attr->lt_mac, ETHERADDRL) == 0) || + (attr->lt_mac[0] & 0x01))) { + free(iocp); + return (DLADM_STATUS_MACADDRINVAL); + } + + bcopy(attr->lt_mac, iocp->lc_mac, ETHERADDRL); + iocp->lc_mac_fixed = attr->lt_mac_fixed; + + rc = i_dladm_aggr_strioctl(fd, LAIOC_CREATE, iocp, len); + if (rc < 0) + status = DLADM_STATUS_LINKINVAL; + + free(iocp); + return (status); +} + +/* + * Invoked to bring up a link aggregation group. + */ +static dladm_status_t +i_dladm_aggr_up(void *arg, dladm_aggr_grp_attr_db_t *attr) +{ + dladm_aggr_up_t *up = (dladm_aggr_up_t *)arg; + dladm_status_t status; + + if (up->lu_key != 0 && up->lu_key != attr->lt_key) + return (DLADM_STATUS_OK); + + up->lu_found = B_TRUE; + + status = i_dladm_aggr_create_sys(up->lu_fd, attr); + if (status != DLADM_STATUS_OK && up->lu_key != 0) + return (status); + + return (DLADM_STATUS_OK); +} + +/* + * Bring up a link aggregation group or all of them if the key is zero. + * If key is 0, walk may terminate early if any of the links fail + */ +dladm_status_t +dladm_aggr_up(uint32_t key, const char *root) +{ + dladm_aggr_up_t up; + dladm_status_t status; + + if ((up.lu_fd = open(DLADM_AGGR_DEV, O_RDWR)) < 0) + return (dladm_errno2status(errno)); + + up.lu_key = key; + up.lu_found = B_FALSE; + + status = i_dladm_aggr_walk_db(i_dladm_aggr_up, &up, root); + if (status != DLADM_STATUS_OK) { + (void) close(up.lu_fd); + return (status); + } + (void) close(up.lu_fd); + + /* + * only return error if user specified key and key was + * not found + */ + if (!up.lu_found && key != 0) + return (DLADM_STATUS_NOTFOUND); + + return (DLADM_STATUS_OK); +} +/* + * Send a delete command to the link aggregation driver. + */ +static int +i_dladm_aggr_delete_sys(int fd, dladm_aggr_grp_attr_t *attr) +{ + laioc_delete_t ioc; + + ioc.ld_key = attr->lg_key; + + return (i_dladm_aggr_strioctl(fd, LAIOC_DELETE, &ioc, sizeof (ioc))); +} + +/* + * Invoked to bring down a link aggregation group. + */ +static int +i_dladm_aggr_down(void *arg, dladm_aggr_grp_attr_t *attr) +{ + dladm_aggr_down_t *down = (dladm_aggr_down_t *)arg; + int fd, errno_save; + + if (down->ld_key != 0 && down->ld_key != attr->lg_key) + return (0); + + down->ld_found = B_TRUE; + + if ((fd = open(DLADM_AGGR_DEV, O_RDWR)) < 0) + return (-1); + + if (i_dladm_aggr_delete_sys(fd, attr) < 0 && down->ld_key != 0) { + errno_save = errno; + (void) close(fd); + errno = errno_save; + return (-1); + } + + (void) close(fd); + return (0); +} + +/* + * Bring down a link aggregation group or all of them if the key is zero. + * If key is 0, walk may terminate early if any of the links fail + */ +dladm_status_t +dladm_aggr_down(uint32_t key) +{ + dladm_aggr_down_t down; + + down.ld_key = key; + down.ld_found = B_FALSE; + + if (dladm_aggr_walk(i_dladm_aggr_down, &down) < 0) + return (dladm_errno2status(errno)); + + /* + * only return error if user specified key and key was + * not found + */ + if (!down.ld_found && key != 0) + return (DLADM_STATUS_NOTFOUND); + + return (DLADM_STATUS_OK); +} + +/* + * For each group found in the DB, invokes (, ). + * + * The following values can be returned by (): + * + * -1: an error occured. This will cause the walk to be terminated, + * and the original DB file to be preserved. + * + * 0: success and write. The walker will write the contents of + * the attribute passed as argument to (), and continue walking + * the entries found in the DB. + * + * 1: skip. The walker should not write the contents of the current + * group attributes to the new DB, but should continue walking + * the entries found in the DB. + */ +static dladm_status_t +i_dladm_aggr_walk_rw_db(int (*fn)(void *, dladm_aggr_grp_attr_db_t *), + void *arg, const char *root) +{ + FILE *fp, *nfp; + int nfd, fn_rc, lock_fd; + char line[MAXLINELEN]; + dladm_aggr_grp_attr_db_t attr; + char *db_file, *tmp_db_file; + char db_file_buf[MAXPATHLEN]; + char tmp_db_file_buf[MAXPATHLEN]; + dladm_status_t status; + + if (root == NULL) { + db_file = DLADM_AGGR_DB; + tmp_db_file = DLADM_AGGR_DB_TMP; + } else { + (void) snprintf(db_file_buf, MAXPATHLEN, "%s%s", root, + DLADM_AGGR_DB); + (void) snprintf(tmp_db_file_buf, MAXPATHLEN, "%s%s", root, + DLADM_AGGR_DB_TMP); + db_file = db_file_buf; + tmp_db_file = tmp_db_file_buf; + } + + if ((lock_fd = i_dladm_aggr_lock_db(F_WRLCK)) < 0) + return (dladm_errno2status(errno)); + + if ((fp = fopen(db_file, "r")) == NULL) { + status = dladm_errno2status(errno); + i_dladm_aggr_unlock_db(lock_fd); + return (status); + } + + if ((nfd = open(tmp_db_file, O_WRONLY|O_CREAT|O_TRUNC, + DLADM_AGGR_DB_PERMS)) == -1) { + status = dladm_errno2status(errno); + (void) fclose(fp); + i_dladm_aggr_unlock_db(lock_fd); + return (status); + } + + if ((nfp = fdopen(nfd, "w")) == NULL) { + status = dladm_errno2status(errno); + (void) close(nfd); + (void) fclose(fp); + (void) unlink(tmp_db_file); + i_dladm_aggr_unlock_db(lock_fd); + return (status); + } + + attr.lt_ports = NULL; + + while (fgets(line, MAXLINELEN, fp) != NULL) { + + /* skip comments */ + if (BLANK_LINE(line)) { + if (fputs(line, nfp) == EOF) { + status = dladm_errno2status(errno); + goto failed; + } + continue; + } + + if (i_dladm_aggr_parse_db(line, &attr) != 0) { + status = DLADM_STATUS_REPOSITORYINVAL; + goto failed; + } + + fn_rc = fn(arg, &attr); + + switch (fn_rc) { + case -1: + /* failure, stop walking */ + status = dladm_errno2status(errno); + goto failed; + case 0: + /* + * Success, write group attributes, which could + * have been modified by fn(). + */ + if (i_dladm_aggr_fput_grp(nfp, &attr) != 0) { + status = dladm_errno2status(errno); + goto failed; + } + break; + case 1: + /* skip current group */ + break; + } + + free(attr.lt_ports); + attr.lt_ports = NULL; + } + + if (getuid() == 0 || geteuid() == 0) { + if (fchmod(nfd, DLADM_AGGR_DB_PERMS) == -1) { + status = dladm_errno2status(errno); + goto failed; + } + + if (fchown(nfd, DLADM_AGGR_DB_OWNER, + DLADM_AGGR_DB_GROUP) == -1) { + status = dladm_errno2status(errno); + goto failed; + } + } + + if (fflush(nfp) == EOF) { + status = dladm_errno2status(errno); + goto failed; + } + + (void) fclose(fp); + (void) fclose(nfp); + + if (rename(tmp_db_file, db_file) == -1) { + status = dladm_errno2status(errno); + (void) unlink(tmp_db_file); + i_dladm_aggr_unlock_db(lock_fd); + return (status); + } + + i_dladm_aggr_unlock_db(lock_fd); + return (DLADM_STATUS_OK); + +failed: + free(attr.lt_ports); + (void) fclose(fp); + (void) fclose(nfp); + (void) unlink(tmp_db_file); + i_dladm_aggr_unlock_db(lock_fd); + + return (status); +} + +/* + * Remove an entry from the DB. + */ +static int +i_dladm_aggr_del_db_fn(void *arg, dladm_aggr_grp_attr_db_t *grp) +{ + delete_db_state_t *state = arg; + + if (grp->lt_key != state->ds_key) + return (0); + + state->ds_found = B_TRUE; + + /* don't save matching group */ + return (1); +} + +static dladm_status_t +i_dladm_aggr_del_db(dladm_aggr_grp_attr_db_t *attr, const char *root) +{ + delete_db_state_t state; + dladm_status_t status; + + state.ds_key = attr->lt_key; + state.ds_found = B_FALSE; + + status = i_dladm_aggr_walk_rw_db(i_dladm_aggr_del_db_fn, &state, root); + if (status != DLADM_STATUS_OK) + return (status); + + if (!state.ds_found) + return (DLADM_STATUS_NOTFOUND); + + return (DLADM_STATUS_OK); +} + +/* + * Modify the properties of an existing group in the DB. + */ +static int +i_dladm_aggr_modify_db_fn(void *arg, dladm_aggr_grp_attr_db_t *grp) +{ + modify_db_state_t *state = arg; + dladm_aggr_modify_attr_t *new_attr = state->us_attr_new; + dladm_aggr_modify_attr_t *old_attr = state->us_attr_old; + + if (grp->lt_key != state->us_key) + return (0); + + state->us_found = B_TRUE; + + if (state->us_mask & DLADM_AGGR_MODIFY_POLICY) { + if (old_attr != NULL) + old_attr->ld_policy = grp->lt_policy; + grp->lt_policy = new_attr->ld_policy; + } + + if (state->us_mask & DLADM_AGGR_MODIFY_MAC) { + if (old_attr != NULL) { + old_attr->ld_mac_fixed = grp->lt_mac_fixed; + bcopy(grp->lt_mac, old_attr->ld_mac, ETHERADDRL); + } + grp->lt_mac_fixed = new_attr->ld_mac_fixed; + bcopy(new_attr->ld_mac, grp->lt_mac, ETHERADDRL); + } + + if (state->us_mask & DLADM_AGGR_MODIFY_LACP_MODE) { + if (old_attr != NULL) + old_attr->ld_lacp_mode = grp->lt_lacp_mode; + grp->lt_lacp_mode = new_attr->ld_lacp_mode; + } + + if (state->us_mask & DLADM_AGGR_MODIFY_LACP_TIMER) { + if (old_attr != NULL) + old_attr->ld_lacp_timer = grp->lt_lacp_timer; + grp->lt_lacp_timer = new_attr->ld_lacp_timer; + } + + /* save modified group */ + return (0); +} + +static dladm_status_t +i_dladm_aggr_modify_db(uint32_t key, uint32_t mask, + dladm_aggr_modify_attr_t *new, dladm_aggr_modify_attr_t *old, + const char *root) +{ + modify_db_state_t state; + dladm_status_t status; + + state.us_key = key; + state.us_mask = mask; + state.us_attr_new = new; + state.us_attr_old = old; + state.us_found = B_FALSE; + + if ((status = i_dladm_aggr_walk_rw_db(i_dladm_aggr_modify_db_fn, + &state, root)) != DLADM_STATUS_OK) { + return (status); + } + + if (!state.us_found) + return (DLADM_STATUS_NOTFOUND); + + return (DLADM_STATUS_OK); +} + +/* + * Add ports to an existing group in the DB. + */ +static int +i_dladm_aggr_add_db_fn(void *arg, dladm_aggr_grp_attr_db_t *grp) +{ + add_db_state_t *state = arg; + dladm_aggr_grp_attr_db_t *attr = state->as_attr; + void *ports; + int i, j; + + if (grp->lt_key != attr->lt_key) + return (0); + + state->as_found = B_TRUE; + + /* are any of the ports to be added already members of the group? */ + for (i = 0; i < grp->lt_nports; i++) { + for (j = 0; j < attr->lt_nports; j++) { + if (strcmp(grp->lt_ports[i].lp_devname, + attr->lt_ports[j].lp_devname) == 0) { + errno = EEXIST; + return (-1); + } + } + } + + /* add groups specified by attr to grp */ + ports = realloc(grp->lt_ports, (grp->lt_nports + + attr->lt_nports) * sizeof (dladm_aggr_port_attr_db_t)); + if (ports == NULL) + return (-1); + grp->lt_ports = ports; + + for (i = 0; i < attr->lt_nports; i++) { + if (strlcpy(grp->lt_ports[grp->lt_nports + i].lp_devname, + attr->lt_ports[i].lp_devname, MAXNAMELEN + 1) >= + MAXNAMELEN + 1) + return (-1); + } + + grp->lt_nports += attr->lt_nports; + + /* save modified group */ + return (0); +} + +static dladm_status_t +i_dladm_aggr_add_db(dladm_aggr_grp_attr_db_t *attr, const char *root) +{ + add_db_state_t state; + dladm_status_t status; + + state.as_attr = attr; + state.as_found = B_FALSE; + + status = i_dladm_aggr_walk_rw_db(i_dladm_aggr_add_db_fn, &state, root); + if (status != DLADM_STATUS_OK) + return (status); + + if (!state.as_found) + return (DLADM_STATUS_NOTFOUND); + + return (DLADM_STATUS_OK); +} + +/* + * Remove ports from an existing group in the DB. + */ + +typedef struct remove_db_state { + dladm_aggr_grp_attr_db_t *rs_attr; + boolean_t rs_found; +} remove_db_state_t; + +static int +i_dladm_aggr_remove_db_fn(void *arg, dladm_aggr_grp_attr_db_t *grp) +{ + remove_db_state_t *state = (remove_db_state_t *)arg; + dladm_aggr_grp_attr_db_t *attr = state->rs_attr; + int i, j, k, nremoved; + boolean_t match; + + if (grp->lt_key != attr->lt_key) + return (0); + + state->rs_found = B_TRUE; + + /* remove the ports specified by attr from the group */ + nremoved = 0; + k = 0; + for (i = 0; i < grp->lt_nports; i++) { + match = B_FALSE; + for (j = 0; j < attr->lt_nports && !match; j++) { + match = (strcmp(grp->lt_ports[i].lp_devname, + attr->lt_ports[j].lp_devname) == 0); + } + if (match) + nremoved++; + else + grp->lt_ports[k++] = grp->lt_ports[i]; + } + + if (nremoved != attr->lt_nports) { + errno = ENOENT; + return (-1); + } + + grp->lt_nports -= nremoved; + + /* save modified group */ + return (0); +} + +static dladm_status_t +i_dladm_aggr_remove_db(dladm_aggr_grp_attr_db_t *attr, const char *root) +{ + remove_db_state_t state; + dladm_status_t status; + + state.rs_attr = attr; + state.rs_found = B_FALSE; + + status = i_dladm_aggr_walk_rw_db(i_dladm_aggr_remove_db_fn, + &state, root); + if (status != DLADM_STATUS_OK) + return (status); + + if (!state.rs_found) + return (DLADM_STATUS_NOTFOUND); + + return (DLADM_STATUS_OK); +} + +/* + * Given a policy string, return a policy mask. Returns B_TRUE on + * success, or B_FALSE if an error occured during parsing. + */ +boolean_t +dladm_aggr_str2policy(const char *str, uint32_t *policy) +{ + int i; + policy_t *pol; + char *token = NULL; + char *lasts; + + *policy = 0; + + while ((token = strtok_r((token == NULL) ? (char *)str : NULL, ",", + &lasts)) != NULL) { + for (i = 0; i < NPOLICIES; i++) { + pol = &policies[i]; + if (strcasecmp(token, pol->pol_name) == 0) { + *policy |= pol->policy; + break; + } + } + if (i == NPOLICIES) + return (B_FALSE); + } + + return (B_TRUE); +} + +/* + * Given a policy mask, returns a printable string, or NULL if the + * policy mask is invalid. It is the responsibility of the caller to + * free the returned string after use. + */ +char * +dladm_aggr_policy2str(uint32_t policy, char *str) +{ + int i, npolicies = 0; + policy_t *pol; + + str[0] = '\0'; + + for (i = 0; i < NPOLICIES; i++) { + pol = &policies[i]; + if ((policy & pol->policy) != 0) { + npolicies++; + if (npolicies > 1) + (void) strcat(str, ","); + (void) strcat(str, pol->pol_name); + } + } + + return (str); +} + +/* + * Given a MAC address string, return the MAC address in the mac_addr + * array. If the MAC address was not explicitly specified, i.e. is + * equal to 'auto', zero out mac-addr and set mac_fixed to B_TRUE. + * Return B_FALSE if a syntax error was encountered, B_FALSE otherwise. + */ +boolean_t +dladm_aggr_str2macaddr(const char *str, boolean_t *mac_fixed, uchar_t *mac_addr) +{ + uchar_t *conv_str; + int mac_len; + + *mac_fixed = (strcmp(str, "auto") != 0); + if (!*mac_fixed) { + bzero(mac_addr, ETHERADDRL); + return (B_TRUE); + } + + conv_str = _link_aton(str, &mac_len); + if (conv_str == NULL) + return (B_FALSE); + + if (mac_len != ETHERADDRL) { + free(conv_str); + return (B_FALSE); + } + + if ((bcmp(zero_mac, conv_str, ETHERADDRL) == 0) || + (conv_str[0] & 0x01)) { + free(conv_str); + return (B_FALSE); + } + + bcopy(conv_str, mac_addr, ETHERADDRL); + free(conv_str); + + return (B_TRUE); +} + +/* + * Returns a string containing a printable representation of a MAC address. + */ +const char * +dladm_aggr_macaddr2str(unsigned char *mac, char *buf) +{ + static char unknown_mac[] = {0, 0, 0, 0, 0, 0}; + + if (buf == NULL) + return (NULL); + + if (bcmp(unknown_mac, mac, ETHERADDRL) == 0) + return (gettext("")); + else + return (_link_ntoa(mac, buf, ETHERADDRL, IFT_OTHER)); +} + +/* + * Given a LACP mode string, find the corresponding LACP mode number. Returns + * B_TRUE if a match was found, B_FALSE otherwise. + */ +boolean_t +dladm_aggr_str2lacpmode(const char *str, aggr_lacp_mode_t *lacp_mode) +{ + int i; + dladm_aggr_lacpmode_t *mode; + + for (i = 0; i < NLACP_MODES; i++) { + mode = &lacp_modes[i]; + if (strncasecmp(str, mode->mode_str, + strlen(mode->mode_str)) == 0) { + *lacp_mode = mode->mode_id; + return (B_TRUE); + } + } + + return (B_FALSE); +} + +/* + * Given a LACP mode number, returns a printable string, or NULL if the + * LACP mode number is invalid. + */ +const char * +dladm_aggr_lacpmode2str(aggr_lacp_mode_t mode_id, char *buf) +{ + int i; + dladm_aggr_lacpmode_t *mode; + + for (i = 0; i < NLACP_MODES; i++) { + mode = &lacp_modes[i]; + if (mode->mode_id == mode_id) { + (void) snprintf(buf, DLADM_STRSIZE, "%s", + mode->mode_str); + return (buf); + } + } + + (void) strlcpy(buf, "unknown", DLADM_STRSIZE); + return (buf); +} + +/* + * Given a LACP timer string, find the corresponding LACP timer number. Returns + * B_TRUE if a match was found, B_FALSE otherwise. + */ +boolean_t +dladm_aggr_str2lacptimer(const char *str, aggr_lacp_timer_t *lacp_timer) +{ + int i; + dladm_aggr_lacptimer_t *timer; + + for (i = 0; i < NLACP_TIMERS; i++) { + timer = &lacp_timers[i]; + if (strncasecmp(str, timer->lt_str, + strlen(timer->lt_str)) == 0) { + *lacp_timer = timer->lt_id; + return (B_TRUE); + } + } + + return (B_FALSE); +} + +/* + * Given a LACP timer, returns a printable string, or NULL if the + * LACP timer number is invalid. + */ +const char * +dladm_aggr_lacptimer2str(aggr_lacp_timer_t timer_id, char *buf) +{ + int i; + dladm_aggr_lacptimer_t *timer; + + for (i = 0; i < NLACP_TIMERS; i++) { + timer = &lacp_timers[i]; + if (timer->lt_id == timer_id) { + (void) snprintf(buf, DLADM_STRSIZE, "%s", + timer->lt_str); + return (buf); + } + } + + (void) strlcpy(buf, "unknown", DLADM_STRSIZE); + return (buf); +} + +const char * +dladm_aggr_portstate2str(aggr_port_state_t state_id, char *buf) +{ + int i; + dladm_aggr_port_state_t *state; + + for (i = 0; i < NPORT_STATES; i++) { + state = &port_states[i]; + if (state->state_id == state_id) { + (void) snprintf(buf, DLADM_STRSIZE, "%s", + state->state_str); + return (buf); + } + } + + (void) strlcpy(buf, "unknown", DLADM_STRSIZE); + return (buf); +} + +#define FPRINTF_ERR(fcall) if ((fcall) < 0) return (-1); + +/* + * Write the attribute of a group to the specified file. Returns 0 on + * success, -1 on failure. + */ +static int +i_dladm_aggr_fput_grp(FILE *fp, dladm_aggr_grp_attr_db_t *attr) +{ + int i; + char addr_str[ETHERADDRL * 3]; + char buf[DLADM_STRSIZE]; + + /* key, policy */ + FPRINTF_ERR(fprintf(fp, "%d\t%s\t", attr->lt_key, + dladm_aggr_policy2str(attr->lt_policy, buf))); + + /* number of ports, ports */ + FPRINTF_ERR(fprintf(fp, "%d\t", attr->lt_nports)); + for (i = 0; i < attr->lt_nports; i++) { + if (i > 0) + FPRINTF_ERR(fprintf(fp, ",")); + FPRINTF_ERR(fprintf(fp, "%s", attr->lt_ports[i].lp_devname)); + } + FPRINTF_ERR(fprintf(fp, "\t")); + + /* MAC address */ + if (!attr->lt_mac_fixed) { + FPRINTF_ERR(fprintf(fp, "auto")); + } else { + FPRINTF_ERR(fprintf(fp, "%s", + dladm_aggr_macaddr2str(attr->lt_mac, addr_str))); + } + FPRINTF_ERR(fprintf(fp, "\t")); + + FPRINTF_ERR(fprintf(fp, "%s\t", + dladm_aggr_lacpmode2str(attr->lt_lacp_mode, buf))); + + FPRINTF_ERR(fprintf(fp, "%s\n", + dladm_aggr_lacptimer2str(attr->lt_lacp_timer, buf))); + + return (0); +} + +static dladm_status_t +i_dladm_aggr_create_db(dladm_aggr_grp_attr_db_t *attr, const char *root) +{ + FILE *fp; + char line[MAXLINELEN]; + uint32_t key; + int lock_fd; + char *db_file; + char db_file_buf[MAXPATHLEN]; + char *endp = NULL; + dladm_status_t status; + + if (root == NULL) { + db_file = DLADM_AGGR_DB; + } else { + (void) snprintf(db_file_buf, MAXPATHLEN, "%s%s", root, + DLADM_AGGR_DB); + db_file = db_file_buf; + } + + if ((lock_fd = i_dladm_aggr_lock_db(F_WRLCK)) < 0) + return (dladm_errno2status(errno)); + + if ((fp = fopen(db_file, "r+")) == NULL && + (fp = fopen(db_file, "w")) == NULL) { + status = dladm_errno2status(errno); + i_dladm_aggr_unlock_db(lock_fd); + return (status); + } + + /* look for existing group with same key */ + while (fgets(line, MAXLINELEN, fp) != NULL) { + char *holder, *lasts; + + /* skip comments */ + if (BLANK_LINE(line)) + continue; + + /* ignore corrupted lines */ + holder = strtok_r(line, " \t", &lasts); + if (holder == NULL) + continue; + + /* port number */ + errno = 0; + key = (int)strtol(holder, &endp, 10); + if (errno != 0 || *endp != '\0') { + status = DLADM_STATUS_REPOSITORYINVAL; + goto done; + } + + if (key == attr->lt_key) { + /* group with key already exists */ + status = DLADM_STATUS_EXIST; + goto done; + } + } + + /* + * If we get here, we've verified that no existing group with + * the same key already exists. It's now time to add the + * new group to the DB. + */ + if (i_dladm_aggr_fput_grp(fp, attr) != 0) { + status = dladm_errno2status(errno); + goto done; + } + + status = DLADM_STATUS_OK; + +done: + (void) fclose(fp); + i_dladm_aggr_unlock_db(lock_fd); + return (status); +} + +/* + * Create a new link aggregation group. Update the configuration + * file and bring it up. + */ +dladm_status_t +dladm_aggr_create(uint32_t key, uint32_t nports, + dladm_aggr_port_attr_db_t *ports, uint32_t policy, boolean_t mac_addr_fixed, + uchar_t *mac_addr, aggr_lacp_mode_t lacp_mode, aggr_lacp_timer_t lacp_timer, + boolean_t tempop, const char *root) +{ + dladm_aggr_grp_attr_db_t attr; + dladm_status_t status; + + if (key == 0 || key > DLADM_AGGR_MAX_KEY) + return (DLADM_STATUS_KEYINVAL); + + attr.lt_key = key; + attr.lt_nports = nports; + attr.lt_ports = ports; + attr.lt_policy = policy; + attr.lt_mac_fixed = mac_addr_fixed; + if (attr.lt_mac_fixed) + bcopy(mac_addr, attr.lt_mac, ETHERADDRL); + else + bzero(attr.lt_mac, ETHERADDRL); + attr.lt_lacp_mode = lacp_mode; + attr.lt_lacp_timer = lacp_timer; + + /* add the link aggregation group to the DB */ + if (!tempop) { + status = i_dladm_aggr_create_db(&attr, root); + if (status != DLADM_STATUS_OK) + return (status); + } else { + dladm_aggr_up_t up; + + up.lu_key = key; + up.lu_found = B_FALSE; + up.lu_fd = open(DLADM_AGGR_DEV, O_RDWR); + if (up.lu_fd < 0) + return (dladm_errno2status(errno)); + + status = i_dladm_aggr_up((void *)&up, &attr); + (void) close(up.lu_fd); + return (status); + } + + /* bring up the link aggregation group */ + status = dladm_aggr_up(key, root); + /* + * If the operation fails because the aggregation already exists, + * then only update the persistent configuration repository and + * return success. + */ + if (status == DLADM_STATUS_EXIST) + status = DLADM_STATUS_OK; + + if (status != DLADM_STATUS_OK && !tempop) + (void) i_dladm_aggr_del_db(&attr, root); + + return (status); +} + +/* + * Modify the parameters of an existing link aggregation group. Update + * the configuration file and pass the changes to the kernel. + */ +dladm_status_t +dladm_aggr_modify(uint32_t key, uint32_t modify_mask, uint32_t policy, + boolean_t mac_fixed, uchar_t *mac_addr, aggr_lacp_mode_t lacp_mode, + aggr_lacp_timer_t lacp_timer, boolean_t tempop, const char *root) +{ + dladm_aggr_modify_attr_t new_attr, old_attr; + dladm_status_t status; + + if (key == 0) + return (DLADM_STATUS_KEYINVAL); + + if (modify_mask & DLADM_AGGR_MODIFY_POLICY) + new_attr.ld_policy = policy; + + if (modify_mask & DLADM_AGGR_MODIFY_MAC) { + new_attr.ld_mac_fixed = mac_fixed; + bcopy(mac_addr, new_attr.ld_mac, ETHERADDRL); + } + + if (modify_mask & DLADM_AGGR_MODIFY_LACP_MODE) + new_attr.ld_lacp_mode = lacp_mode; + + if (modify_mask & DLADM_AGGR_MODIFY_LACP_TIMER) + new_attr.ld_lacp_timer = lacp_timer; + + /* update the DB */ + if (!tempop && ((status = i_dladm_aggr_modify_db(key, modify_mask, + &new_attr, &old_attr, root)) != DLADM_STATUS_OK)) { + return (status); + } + + status = i_dladm_aggr_modify_sys(key, modify_mask, &new_attr); + if (status != DLADM_STATUS_OK && !tempop) { + (void) i_dladm_aggr_modify_db(key, modify_mask, &old_attr, + NULL, root); + } + + return (status); +} + +/* + * Delete a previously created link aggregation group. + */ +dladm_status_t +dladm_aggr_delete(uint32_t key, boolean_t tempop, const char *root) +{ + dladm_aggr_grp_attr_db_t db_attr; + dladm_status_t status; + + if (key == 0) + return (DLADM_STATUS_KEYINVAL); + + if (tempop) { + dladm_aggr_down_t down; + dladm_aggr_grp_attr_t sys_attr; + + down.ld_key = key; + down.ld_found = B_FALSE; + sys_attr.lg_key = key; + if (i_dladm_aggr_down((void *)&down, &sys_attr) < 0) + return (dladm_errno2status(errno)); + else + return (DLADM_STATUS_OK); + } else { + status = dladm_aggr_down(key); + + /* + * Only continue to delete the configuration repository + * either if we successfully delete the active aggregation + * or if the aggregation is not found. + */ + if (status != DLADM_STATUS_OK && + status != DLADM_STATUS_NOTFOUND) { + return (status); + } + } + + if (tempop) + return (DLADM_STATUS_OK); + + db_attr.lt_key = key; + return (i_dladm_aggr_del_db(&db_attr, root)); +} + +/* + * Add one or more ports to an existing link aggregation. + */ +dladm_status_t +dladm_aggr_add(uint32_t key, uint32_t nports, dladm_aggr_port_attr_db_t *ports, + boolean_t tempop, const char *root) +{ + dladm_aggr_grp_attr_db_t attr; + dladm_status_t status; + + if (key == 0) + return (DLADM_STATUS_KEYINVAL); + + bzero(&attr, sizeof (attr)); + attr.lt_key = key; + attr.lt_nports = nports; + attr.lt_ports = ports; + + if (!tempop && + ((status = i_dladm_aggr_add_db(&attr, root)) != DLADM_STATUS_OK)) { + return (status); + } + + status = i_dladm_aggr_add_rem_sys(&attr, LAIOC_ADD); + if (status != DLADM_STATUS_OK && !tempop) + (void) i_dladm_aggr_remove_db(&attr, root); + + return (status); +} + +/* + * Remove one or more ports from an existing link aggregation. + */ +dladm_status_t +dladm_aggr_remove(uint32_t key, uint32_t nports, + dladm_aggr_port_attr_db_t *ports, boolean_t tempop, const char *root) +{ + dladm_aggr_grp_attr_db_t attr; + dladm_status_t status; + + if (key == 0) + return (DLADM_STATUS_KEYINVAL); + + bzero(&attr, sizeof (attr)); + attr.lt_key = key; + attr.lt_nports = nports; + attr.lt_ports = ports; + + if (!tempop && + ((status = i_dladm_aggr_remove_db(&attr, root)) != + DLADM_STATUS_OK)) { + return (status); + } + + status = i_dladm_aggr_add_rem_sys(&attr, LAIOC_REMOVE); + if (status != DLADM_STATUS_OK && !tempop) + (void) i_dladm_aggr_add_db(&attr, root); + + return (status); +} diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/libdlaggr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libdladm/common/libdlaggr.h Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,113 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LIBDLAGGR_H +#define _LIBDLAGGR_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file includes structures, macros and routines used by aggregation link + * administration. + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Modification flags sent with the LAIOC_MODIFY ioctl + */ +#define DLADM_AGGR_MODIFY_POLICY 0x01 +#define DLADM_AGGR_MODIFY_MAC 0x02 +#define DLADM_AGGR_MODIFY_LACP_MODE 0x04 +#define DLADM_AGGR_MODIFY_LACP_TIMER 0x08 + +typedef struct dladm_aggr_port_attr_db { + char lp_devname[MAXNAMELEN + 1]; +} dladm_aggr_port_attr_db_t; + +typedef struct dladm_aggr_port_attr { + char lp_devname[MAXNAMELEN + 1]; + uchar_t lp_mac[ETHERADDRL]; + aggr_port_state_t lp_state; + aggr_lacp_state_t lp_lacp_state; +} dladm_aggr_port_attr_t; + +typedef struct dladm_aggr_grp_attr { + uint32_t lg_key; + uint32_t lg_nports; + dladm_aggr_port_attr_t *lg_ports; + uint32_t lg_policy; + uchar_t lg_mac[ETHERADDRL]; + boolean_t lg_mac_fixed; + aggr_lacp_mode_t lg_lacp_mode; + aggr_lacp_timer_t lg_lacp_timer; +} dladm_aggr_grp_attr_t; + +extern dladm_status_t dladm_aggr_create(uint32_t, uint32_t, + dladm_aggr_port_attr_db_t *, uint32_t, boolean_t, + uchar_t *, aggr_lacp_mode_t, aggr_lacp_timer_t, + boolean_t, const char *); +extern dladm_status_t dladm_aggr_delete(uint32_t, boolean_t, const char *); +extern dladm_status_t dladm_aggr_add(uint32_t, uint32_t, + dladm_aggr_port_attr_db_t *, boolean_t, + const char *); +extern dladm_status_t dladm_aggr_remove(uint32_t, uint32_t, + dladm_aggr_port_attr_db_t *, boolean_t, + const char *); +extern dladm_status_t dladm_aggr_modify(uint32_t, uint32_t, uint32_t, + boolean_t, uchar_t *, aggr_lacp_mode_t, + aggr_lacp_timer_t, boolean_t, const char *); +extern dladm_status_t dladm_aggr_up(uint32_t, const char *); +extern dladm_status_t dladm_aggr_down(uint32_t); + +extern boolean_t dladm_aggr_str2policy(const char *, uint32_t *); +extern char *dladm_aggr_policy2str(uint32_t, char *); +extern boolean_t dladm_aggr_str2macaddr(const char *, boolean_t *, + uchar_t *); +extern const char *dladm_aggr_macaddr2str(unsigned char *, char *); + +extern boolean_t dladm_aggr_str2lacpmode(const char *, + aggr_lacp_mode_t *); +extern const char *dladm_aggr_lacpmode2str(aggr_lacp_mode_t, char *); +extern boolean_t dladm_aggr_str2lacptimer(const char *, + aggr_lacp_timer_t *); +extern const char *dladm_aggr_lacptimer2str(aggr_lacp_timer_t, char *); + +extern const char *dladm_aggr_portstate2str(aggr_port_state_t, char *); + +extern int dladm_aggr_walk(int (*)(void *, + dladm_aggr_grp_attr_t *), void *); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBDLAGGR_H */ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/libdllink.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libdladm/common/libdllink.c Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,391 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct dladm_dev { + char dd_name[IFNAMSIZ]; + struct dladm_dev *dd_next; +} dladm_dev_t; + +typedef struct dladm_walk { + dladm_dev_t *dw_dev_list; +} dladm_walk_t; + +/* + * Return the attributes of the specified datalink from the DLD driver. + */ +static int +i_dladm_info(int fd, const char *name, dladm_attr_t *dap) +{ + dld_ioc_attr_t dia; + + if (strlen(name) >= IFNAMSIZ) { + errno = EINVAL; + return (-1); + } + + (void) strlcpy(dia.dia_name, name, IFNAMSIZ); + + if (i_dladm_ioctl(fd, DLDIOCATTR, &dia, sizeof (dia)) < 0) + return (-1); + + (void) strlcpy(dap->da_dev, dia.dia_dev, MAXNAMELEN); + dap->da_max_sdu = dia.dia_max_sdu; + dap->da_vid = dia.dia_vid; + + return (0); +} + +/* + * Adds a datalink to the array corresponding to arg. + */ +static void +i_dladm_nt_net_add(void *arg, char *name) +{ + dladm_walk_t *dwp = arg; + dladm_dev_t *ddp = dwp->dw_dev_list; + dladm_dev_t **lastp = &dwp->dw_dev_list; + + while (ddp) { + /* + * Skip duplicates. + */ + if (strcmp(ddp->dd_name, name) == 0) + return; + + lastp = &ddp->dd_next; + ddp = ddp->dd_next; + } + + if ((ddp = malloc(sizeof (*ddp))) == NULL) + return; + + (void) strlcpy(ddp->dd_name, name, IFNAMSIZ); + ddp->dd_next = NULL; + *lastp = ddp; +} + +/* + * Walker callback invoked for each DDI_NT_NET node. + */ +static int +i_dladm_nt_net_walk(di_node_t node, di_minor_t minor, void *arg) +{ + char linkname[DLPI_LINKNAME_MAX]; + dlpi_handle_t dh; + + if (dlpi_makelink(linkname, di_minor_name(minor), + di_instance(node)) != DLPI_SUCCESS) + return (DI_WALK_CONTINUE); + + if (dlpi_open(linkname, &dh, 0) == DLPI_SUCCESS) { + i_dladm_nt_net_add(arg, linkname); + dlpi_close(dh); + } + return (DI_WALK_CONTINUE); +} + +/* + * Hold a data-link. + */ +static int +i_dladm_hold_link(const char *name, zoneid_t zoneid, boolean_t docheck) +{ + int fd; + dld_hold_vlan_t dhv; + + if (strlen(name) >= IFNAMSIZ) { + errno = EINVAL; + return (-1); + } + + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) + return (-1); + + bzero(&dhv, sizeof (dld_hold_vlan_t)); + (void) strlcpy(dhv.dhv_name, name, IFNAMSIZ); + dhv.dhv_zid = zoneid; + dhv.dhv_docheck = docheck; + + if (i_dladm_ioctl(fd, DLDIOCHOLDVLAN, &dhv, sizeof (dhv)) < 0) { + int olderrno = errno; + + (void) close(fd); + errno = olderrno; + return (-1); + } + + (void) close(fd); + return (0); +} + +/* + * Release a data-link. + */ +static int +i_dladm_rele_link(const char *name, zoneid_t zoneid, boolean_t docheck) +{ + int fd; + dld_hold_vlan_t dhv; + + if (strlen(name) >= IFNAMSIZ) { + errno = EINVAL; + return (-1); + } + + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) + return (-1); + + bzero(&dhv, sizeof (dld_hold_vlan_t)); + (void) strlcpy(dhv.dhv_name, name, IFNAMSIZ); + dhv.dhv_zid = zoneid; + dhv.dhv_docheck = docheck; + + if (i_dladm_ioctl(fd, DLDIOCRELEVLAN, &dhv, sizeof (dhv)) < 0) { + int olderrno = errno; + + (void) close(fd); + errno = olderrno; + return (-1); + } + + (void) close(fd); + return (0); +} + +/* + * Invoke the specified callback function for each active DDI_NT_NET + * node. + */ +int +dladm_walk(void (*fn)(void *, const char *), void *arg) +{ + di_node_t root; + dladm_walk_t dw; + dladm_dev_t *ddp, *last_ddp; + + if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) { + errno = EFAULT; + return (-1); + } + dw.dw_dev_list = NULL; + + (void) di_walk_minor(root, DDI_NT_NET, DI_CHECK_ALIAS, &dw, + i_dladm_nt_net_walk); + + di_fini(root); + + ddp = dw.dw_dev_list; + while (ddp) { + fn(arg, ddp->dd_name); + last_ddp = ddp; + ddp = ddp->dd_next; + free(last_ddp); + } + + return (0); +} + +/* + * MAC Administration Library. + * + * This library is used by administration tools such as dladm(1M) to + * iterate through the list of MAC interfaces + * + */ + +typedef struct dladm_mac_dev { + char dm_name[MAXNAMELEN]; + struct dladm_mac_dev *dm_next; +} dladm_mac_dev_t; + +typedef struct macadm_walk { + dladm_mac_dev_t *dmd_dev_list; +} dladm_mac_walk_t; + +/* + * Local callback invoked for each DDI_NT_NET node. + */ +/* ARGSUSED */ +static int +i_dladm_mac_walk(di_node_t node, di_minor_t minor, void *arg) +{ + dladm_mac_walk_t *dmwp = arg; + dladm_mac_dev_t *dmdp = dmwp->dmd_dev_list; + dladm_mac_dev_t **last_dmdp = &dmwp->dmd_dev_list; + char mac[MAXNAMELEN]; + + (void) snprintf(mac, MAXNAMELEN, "%s%d", + di_driver_name(node), di_instance(node)); + + /* + * Skip aggregations. + */ + if (strcmp("aggr", di_driver_name(node)) == 0) + return (DI_WALK_CONTINUE); + + while (dmdp) { + /* + * Skip duplicates. + */ + if (strcmp(dmdp->dm_name, mac) == 0) + return (DI_WALK_CONTINUE); + + last_dmdp = &dmdp->dm_next; + dmdp = dmdp->dm_next; + } + + if ((dmdp = malloc(sizeof (*dmdp))) == NULL) + return (DI_WALK_CONTINUE); + + (void) strlcpy(dmdp->dm_name, mac, MAXNAMELEN); + dmdp->dm_next = NULL; + *last_dmdp = dmdp; + + return (DI_WALK_CONTINUE); +} + +/* + * Invoke the specified callback for each DDI_NT_MAC node. + */ +int +dladm_mac_walk(void (*fn)(void *, const char *), void *arg) +{ + di_node_t root; + dladm_mac_walk_t dmw; + dladm_mac_dev_t *dmdp, *next; + + if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) + return (-1); + + dmw.dmd_dev_list = NULL; + + (void) di_walk_minor(root, DDI_NT_NET, DI_CHECK_ALIAS, &dmw, + i_dladm_mac_walk); + + di_fini(root); + + dmdp = dmw.dmd_dev_list; + for (dmdp = dmw.dmd_dev_list; dmdp != NULL; dmdp = next) { + next = dmdp->dm_next; + (*fn)(arg, dmdp->dm_name); + free(dmdp); + } + + return (0); +} + +/* + * Returns the current attributes of the specified datalink. + */ +int +dladm_info(const char *name, dladm_attr_t *dap) +{ + int fd; + + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) + return (-1); + + if (i_dladm_info(fd, name, dap) < 0) + goto failed; + + (void) close(fd); + return (0); + +failed: + (void) close(fd); + return (-1); +} + +const char * +dladm_linkstate2str(link_state_t state, char *buf) +{ + const char *s; + + switch (state) { + case LINK_STATE_UP: + s = "up"; + break; + case LINK_STATE_DOWN: + s = "down"; + break; + default: + s = "unknown"; + break; + } + (void) snprintf(buf, DLADM_STRSIZE, "%s", s); + return (buf); +} + +const char * +dladm_linkduplex2str(link_duplex_t duplex, char *buf) +{ + const char *s; + + switch (duplex) { + case LINK_DUPLEX_FULL: + s = "full"; + break; + case LINK_DUPLEX_HALF: + s = "half"; + break; + default: + s = "unknown"; + break; + } + (void) snprintf(buf, DLADM_STRSIZE, "%s", s); + return (buf); +} + +/* + * Do a "hold" operation to a link. + */ +int +dladm_hold_link(const char *name, zoneid_t zoneid, boolean_t docheck) +{ + return (i_dladm_hold_link(name, zoneid, docheck)); +} + +/* + * Do a "release" operation to a link. + */ +int +dladm_rele_link(const char *name, zoneid_t zoneid, boolean_t docheck) +{ + return (i_dladm_rele_link(name, zoneid, docheck)); +} diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/libdllink.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libdladm/common/libdllink.h Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,104 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LIBDLLINK_H +#define _LIBDLLINK_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file includes strcutures, macros and routines used by general + * link administration, which applies not limited to one specific + * type of link. + */ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct dladm_attr { + char da_dev[MAXNAMELEN]; + uint_t da_max_sdu; + uint16_t da_vid; +} dladm_attr_t; + +/* + * Maximum size of secobj value. Note that it should not be greater than + * DLD_SECOBJ_VAL_MAX. + */ +#define DLADM_SECOBJ_VAL_MAX 256 + +/* + * Maximum size of secobj name. Note that it should not be greater than + * DLD_SECOBJ_NAME_MAX. + */ +#define DLADM_SECOBJ_NAME_MAX 32 + +#define DLADM_PROP_VAL_MAX 25 + +#define DLADM_SECOBJ_CLASS_WEP 0 +typedef int dladm_secobj_class_t; + +typedef void (dladm_walkcb_t)(void *, const char *); + +extern int dladm_walk(dladm_walkcb_t *, void *); +extern int dladm_mac_walk(void (*fn)(void *, const char *), void *); +extern int dladm_info(const char *, dladm_attr_t *); +extern int dladm_hold_link(const char *, zoneid_t, boolean_t); +extern int dladm_rele_link(const char *, zoneid_t, boolean_t); + +extern dladm_status_t dladm_set_prop(const char *, const char *, + char **, uint_t, uint_t, char **); +extern dladm_status_t dladm_get_prop(const char *, dladm_prop_type_t, + const char *, char **, uint_t *); +extern dladm_status_t dladm_walk_prop(const char *, void *, + boolean_t (*)(void *, const char *)); +extern dladm_status_t dladm_set_secobj(const char *, dladm_secobj_class_t, + uint8_t *, uint_t, uint_t); +extern dladm_status_t dladm_get_secobj(const char *, dladm_secobj_class_t *, + uint8_t *, uint_t *, uint_t); +extern dladm_status_t dladm_unset_secobj(const char *, uint_t); +extern dladm_status_t dladm_walk_secobj(void *, + boolean_t (*)(void *, const char *), uint_t); + +extern const char *dladm_linkstate2str(link_state_t, char *); +extern const char *dladm_linkduplex2str(link_duplex_t, char *); +extern const char *dladm_secobjclass2str(dladm_secobj_class_t, char *); +extern dladm_status_t dladm_str2secobjclass(const char *, + dladm_secobj_class_t *); + +extern dladm_status_t dladm_init_linkprop(void); +extern dladm_status_t dladm_init_secobj(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBDLLINK_H */ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/libdlwlan.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libdladm/common/libdlwlan.c Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,1937 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct val_desc { + char *vd_name; + uint_t vd_val; +} val_desc_t; + +struct prop_desc; + +typedef dladm_status_t wl_pd_getf_t(int, wldp_t *, char **, uint_t *); +typedef dladm_status_t wl_pd_setf_t(int, wldp_t *, val_desc_t *, uint_t); +typedef dladm_status_t wl_pd_checkf_t(int, wldp_t *, struct prop_desc *, + char **, uint_t, val_desc_t **); +typedef struct prop_desc { + char *pd_name; + val_desc_t pd_defval; + val_desc_t *pd_modval; + uint_t pd_nmodval; + wl_pd_setf_t *pd_set; + wl_pd_getf_t *pd_getmod; + wl_pd_getf_t *pd_get; + wl_pd_checkf_t *pd_check; +} prop_desc_t; + +static int do_get_bsstype(int, wldp_t *); +static int do_get_essid(int, wldp_t *); +static int do_get_bssid(int, wldp_t *); +static int do_get_signal(int, wldp_t *); +static int do_get_encryption(int, wldp_t *); +static int do_get_authmode(int, wldp_t *); +static int do_get_linkstatus(int, wldp_t *); +static int do_get_esslist(int, wldp_t *); +static int do_get_rate(int, wldp_t *); +static int do_get_phyconf(int, wldp_t *); +static int do_get_powermode(int, wldp_t *); +static int do_get_radio(int, wldp_t *); +static int do_get_mode(int, wldp_t *); + +static int do_set_bsstype(int, wldp_t *, dladm_wlan_bsstype_t *); +static int do_set_authmode(int, wldp_t *, dladm_wlan_auth_t *); +static int do_set_encryption(int, wldp_t *, dladm_wlan_secmode_t *); +static int do_set_essid(int, wldp_t *, dladm_wlan_essid_t *); +static int do_set_createibss(int, wldp_t *, boolean_t *); +static int do_set_wepkey(int, wldp_t *, dladm_wlan_wepkey_t *, uint_t); +static int do_set_rate(int, wldp_t *, dladm_wlan_rates_t *); +static int do_set_powermode(int, wldp_t *, dladm_wlan_powermode_t *); +static int do_set_radio(int, wldp_t *, dladm_wlan_radio_t *); +static int do_set_channel(int, wldp_t *, dladm_wlan_channel_t *); + +static int open_link(const char *); +static int do_scan(int, wldp_t *); +static int do_disconnect(int, wldp_t *); +static boolean_t find_val_by_name(const char *, val_desc_t *, uint_t, uint_t *); +static boolean_t find_name_by_val(uint_t, val_desc_t *, uint_t, char **); +static void generate_essid(dladm_wlan_essid_t *); + +static dladm_status_t dladm_wlan_wlresult2status(wldp_t *); + +static wl_pd_getf_t do_get_rate_mod, do_get_rate_prop, do_get_channel_prop, + do_get_powermode_prop, do_get_radio_prop; +static wl_pd_setf_t do_set_rate_prop, do_set_powermode_prop, + do_set_radio_prop; +static wl_pd_checkf_t do_check_prop, do_check_rate; + +static val_desc_t linkstatus_vals[] = { + { "disconnected", DLADM_WLAN_LINKSTATUS_DISCONNECTED }, + { "connected", DLADM_WLAN_LINKSTATUS_CONNECTED } +}; + +static val_desc_t secmode_vals[] = { + { "none", DLADM_WLAN_SECMODE_NONE }, + { "wep", DLADM_WLAN_SECMODE_WEP } +}; + +static val_desc_t strength_vals[] = { + { "very weak", DLADM_WLAN_STRENGTH_VERY_WEAK }, + { "weak", DLADM_WLAN_STRENGTH_WEAK }, + { "good", DLADM_WLAN_STRENGTH_GOOD }, + { "very good", DLADM_WLAN_STRENGTH_VERY_GOOD }, + { "excellent", DLADM_WLAN_STRENGTH_EXCELLENT } +}; + +static val_desc_t mode_vals[] = { + { "a", DLADM_WLAN_MODE_80211A }, + { "b", DLADM_WLAN_MODE_80211B }, + { "g", DLADM_WLAN_MODE_80211G }, +}; + +static val_desc_t auth_vals[] = { + { "open", DLADM_WLAN_AUTH_OPEN }, + { "shared", DLADM_WLAN_AUTH_SHARED } +}; + +static val_desc_t bsstype_vals[] = { + { "bss", DLADM_WLAN_BSSTYPE_BSS }, + { "ibss", DLADM_WLAN_BSSTYPE_IBSS }, + { "any", DLADM_WLAN_BSSTYPE_ANY } +}; + +static val_desc_t radio_vals[] = { + { "on", DLADM_WLAN_RADIO_ON }, + { "off", DLADM_WLAN_RADIO_OFF } +}; + +static val_desc_t powermode_vals[] = { + { "off", DLADM_WLAN_PM_OFF }, + { "fast", DLADM_WLAN_PM_FAST }, + { "max", DLADM_WLAN_PM_MAX } +}; + +#define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) +static prop_desc_t prop_table[] = { + + { "channel", { NULL, 0 }, NULL, 0, + NULL, NULL, do_get_channel_prop, do_check_prop}, + + { "powermode", { "off", DLADM_WLAN_PM_OFF }, powermode_vals, + VALCNT(powermode_vals), + do_set_powermode_prop, NULL, + do_get_powermode_prop, do_check_prop}, + + { "radio", { "on", DLADM_WLAN_RADIO_ON }, radio_vals, + VALCNT(radio_vals), + do_set_radio_prop, NULL, + do_get_radio_prop, do_check_prop}, + + { "speed", { "", 0 }, NULL, 0, + do_set_rate_prop, do_get_rate_mod, + do_get_rate_prop, do_check_rate} +}; +/* + * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all + * rates to be retrieved. However, we cannot increase it at this + * time because it will break binary comatibility with unbundled + * WiFi drivers and utilities. So for now we define an additional + * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. + */ +#define MAX_SUPPORT_RATES 64 +#define DLADM_WLAN_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) +#define IS_CONNECTED(gbuf) \ + ((*(wl_linkstatus_t *)((gbuf)->wldp_buf) == WL_CONNECTED)) + +static dladm_status_t +dladm_wlan_wlresult2status(wldp_t *gbuf) +{ + switch (gbuf->wldp_result) { + case WL_SUCCESS: + return (DLADM_STATUS_OK); + + case WL_NOTSUPPORTED: + case WL_LACK_FEATURE: + return (DLADM_STATUS_NOTSUP); + + case WL_READONLY: + return (DLADM_STATUS_PROPRDONLY); + + default: + break; + } + + return (DLADM_STATUS_FAILED); +} + +static int +open_link(const char *link) +{ + char linkname[MAXPATHLEN]; + wldp_t *gbuf; + int fd; + + if (link == NULL) + return (-1); + + (void) snprintf(linkname, MAXPATHLEN, "/dev/%s", link); + if ((fd = open(linkname, O_RDWR)) < 0) + return (-1); + + if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { + (void) close(fd); + return (-1); + } + + /* + * Check to see if the link is wireless. + */ + if (do_get_bsstype(fd, gbuf) < 0) { + free(gbuf); + (void) close(fd); + return (-1); + } + + free(gbuf); + return (fd); +} + +static dladm_wlan_mode_t +do_convert_mode(wl_phy_conf_t *phyp) +{ + switch (phyp->wl_phy_fhss_conf.wl_fhss_subtype) { + case WL_ERP: + return (DLADM_WLAN_MODE_80211G); + case WL_OFDM: + return (DLADM_WLAN_MODE_80211A); + case WL_DSSS: + case WL_FHSS: + return (DLADM_WLAN_MODE_80211B); + default: + break; + } + + return (DLADM_WLAN_MODE_NONE); +} + +static boolean_t +do_convert_chan(wl_phy_conf_t *phyp, uint32_t *channelp) +{ + wl_fhss_t *wlfp = &phyp->wl_phy_fhss_conf; + wl_ofdm_t *wlop = &phyp->wl_phy_ofdm_conf; + + switch (wlfp->wl_fhss_subtype) { + case WL_FHSS: + case WL_DSSS: + case WL_IRBASE: + case WL_HRDS: + case WL_ERP: + *channelp = wlfp->wl_fhss_channel; + break; + case WL_OFDM: + *channelp = DLADM_WLAN_OFDM2CHAN(wlop->wl_ofdm_frequency); + break; + default: + return (B_FALSE); + } + return (B_TRUE); +} + +#define IEEE80211_RATE 0x7f +static void +fill_wlan_attr(wl_ess_conf_t *wlp, dladm_wlan_attr_t *attrp) +{ + int i; + + (void) memset(attrp, 0, sizeof (*attrp)); + + (void) snprintf(attrp->wa_essid.we_bytes, DLADM_WLAN_MAX_ESSID_LEN, + "%s", wlp->wl_ess_conf_essid.wl_essid_essid); + attrp->wa_valid |= DLADM_WLAN_ATTR_ESSID; + + (void) memcpy(attrp->wa_bssid.wb_bytes, wlp->wl_ess_conf_bssid, + DLADM_WLAN_BSSID_LEN); + attrp->wa_valid |= DLADM_WLAN_ATTR_BSSID; + + attrp->wa_secmode = (wlp->wl_ess_conf_wepenabled == + WL_ENC_WEP ? DLADM_WLAN_SECMODE_WEP : DLADM_WLAN_SECMODE_NONE); + attrp->wa_valid |= DLADM_WLAN_ATTR_SECMODE; + + attrp->wa_bsstype = (wlp->wl_ess_conf_bsstype == WL_BSS_BSS ? + DLADM_WLAN_BSSTYPE_BSS : DLADM_WLAN_BSSTYPE_IBSS); + attrp->wa_valid |= DLADM_WLAN_ATTR_BSSTYPE; + + attrp->wa_auth = (wlp->wl_ess_conf_authmode == 0 ? + DLADM_WLAN_AUTH_OPEN : DLADM_WLAN_AUTH_SHARED); + attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH; + + attrp->wa_strength = DLADM_WLAN_SIGNAL2STRENGTH(wlp->wl_ess_conf_sl); + attrp->wa_valid |= DLADM_WLAN_ATTR_STRENGTH; + + attrp->wa_mode = do_convert_mode((wl_phy_conf_t *)&wlp->wl_phy_conf); + attrp->wa_valid |= DLADM_WLAN_ATTR_MODE; + + for (i = 0; i < MAX_SCAN_SUPPORT_RATES; i++) { + wlp->wl_supported_rates[i] &= IEEE80211_RATE; + if (wlp->wl_supported_rates[i] > attrp->wa_speed) + attrp->wa_speed = wlp->wl_supported_rates[i]; + } + if (attrp->wa_speed > 0) + attrp->wa_valid |= DLADM_WLAN_ATTR_SPEED; + + if (do_convert_chan((wl_phy_conf_t *)&wlp->wl_phy_conf, + &attrp->wa_channel)) + attrp->wa_valid |= DLADM_WLAN_ATTR_CHANNEL; +} + +dladm_status_t +dladm_wlan_scan(const char *link, void *arg, + boolean_t (*func)(void *, dladm_wlan_attr_t *)) +{ + int fd, i; + uint32_t count; + wl_ess_conf_t *wlp; + wldp_t *gbuf; + dladm_wlan_attr_t wlattr; + dladm_status_t status; + boolean_t connected; + + if ((fd = open_link(link)) < 0) + return (DLADM_STATUS_LINKINVAL); + + if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + if (do_get_linkstatus(fd, gbuf) < 0) { + status = DLADM_STATUS_FAILED; + goto done; + } + connected = IS_CONNECTED(gbuf); + + if (do_scan(fd, gbuf) < 0) { + status = DLADM_STATUS_FAILED; + goto done; + } + + if (do_get_esslist(fd, gbuf) < 0) { + status = DLADM_STATUS_FAILED; + goto done; + } + + wlp = ((wl_ess_list_t *)gbuf->wldp_buf)->wl_ess_list_ess; + count = ((wl_ess_list_t *)(gbuf->wldp_buf))->wl_ess_list_num; + + for (i = 0; i < count; i++, wlp++) { + fill_wlan_attr(wlp, &wlattr); + if (!func(arg, &wlattr)) + break; + } + + if (!connected) { + if (do_get_linkstatus(fd, gbuf) < 0) { + status = DLADM_STATUS_FAILED; + goto done; + } + if (IS_CONNECTED(gbuf)) + (void) do_disconnect(fd, gbuf); + } + + status = DLADM_STATUS_OK; +done: + free(gbuf); + (void) close(fd); + return (status); +} + +/* + * Structures used in building the list of eligible WLANs to connect to. + * Specifically, `connect_state' has the WLAN attributes that must be matched + * (in `cs_attr') and a growing list of WLANs that matched those attributes + * chained through `cs_list'. Each element in the list is of type `attr_node' + * and has the matching WLAN's attributes and a pointer to the next element. + * For convenience, `cs_count' tracks the number of elements in the list. + */ +typedef struct attr_node { + dladm_wlan_attr_t an_attr; + struct attr_node *an_next; +} attr_node_t; + +typedef struct connect_state { + dladm_wlan_attr_t *cs_attr; + uint_t cs_count; + attr_node_t *cs_list; +} connect_state_t; + +/* + * Compare two sets of WLAN attributes. For now, we only consider strength + * and speed (in that order), which matches the documented default policy for + * dladm_wlan_connect(). + */ +static int +attr_compare(const void *p1, const void *p2) +{ + dladm_wlan_attr_t *attrp1, *attrp2; + + attrp1 = (*(dladm_wlan_attr_t **)p1); + attrp2 = (*(dladm_wlan_attr_t **)p2); + + if (attrp1->wa_strength < attrp2->wa_strength) + return (1); + + if (attrp1->wa_strength > attrp2->wa_strength) + return (-1); + + return (attrp2->wa_speed - attrp1->wa_speed); +} + +/* + * Callback function used by dladm_wlan_connect() to filter out unwanted + * WLANs when scanning for available WLANs. Always returns B_TRUE to + * continue the scan. + */ +static boolean_t +connect_cb(void *arg, dladm_wlan_attr_t *attrp) +{ + attr_node_t *nodep; + dladm_wlan_attr_t *fattrp; + connect_state_t *statep = (connect_state_t *)arg; + + fattrp = statep->cs_attr; + if (fattrp == NULL) + goto append; + + if ((fattrp->wa_valid & attrp->wa_valid) != fattrp->wa_valid) + return (B_TRUE); + + if ((fattrp->wa_valid & DLADM_WLAN_ATTR_ESSID) != 0 && + strncmp(fattrp->wa_essid.we_bytes, attrp->wa_essid.we_bytes, + DLADM_WLAN_MAX_ESSID_LEN) != 0) + return (B_TRUE); + + if ((fattrp->wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0 && + fattrp->wa_secmode != attrp->wa_secmode) + return (B_TRUE); + + if ((fattrp->wa_valid & DLADM_WLAN_ATTR_MODE) != 0 && + fattrp->wa_mode != attrp->wa_mode) + return (B_TRUE); + + if ((fattrp->wa_valid & DLADM_WLAN_ATTR_STRENGTH) != 0 && + fattrp->wa_strength != attrp->wa_strength) + return (B_TRUE); + + if ((fattrp->wa_valid & DLADM_WLAN_ATTR_SPEED) != 0 && + fattrp->wa_speed != attrp->wa_speed) + return (B_TRUE); + + if ((fattrp->wa_valid & DLADM_WLAN_ATTR_AUTH) != 0) { + attrp->wa_auth = fattrp->wa_auth; + attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH; + } + + if ((fattrp->wa_valid & DLADM_WLAN_ATTR_BSSTYPE) != 0 && + fattrp->wa_bsstype != attrp->wa_bsstype) + return (B_TRUE); + + if ((fattrp->wa_valid & DLADM_WLAN_ATTR_BSSID) != 0 && + memcmp(fattrp->wa_bssid.wb_bytes, attrp->wa_bssid.wb_bytes, + DLADM_WLAN_BSSID_LEN) != 0) + return (B_TRUE); +append: + nodep = malloc(sizeof (attr_node_t)); + if (nodep == NULL) + return (B_TRUE); + + (void) memcpy(&nodep->an_attr, attrp, sizeof (dladm_wlan_attr_t)); + nodep->an_next = statep->cs_list; + statep->cs_list = nodep; + statep->cs_count++; + + return (B_TRUE); +} + +static dladm_status_t +do_connect(int fd, wldp_t *gbuf, dladm_wlan_attr_t *attrp, + boolean_t create_ibss, void *keys, uint_t key_count, int timeout) +{ + dladm_wlan_secmode_t secmode; + dladm_wlan_auth_t authmode; + dladm_wlan_bsstype_t bsstype; + dladm_wlan_essid_t essid; + boolean_t essid_valid = B_FALSE; + dladm_wlan_channel_t channel; + hrtime_t start; + + if ((attrp->wa_valid & DLADM_WLAN_ATTR_CHANNEL) != 0) { + channel = attrp->wa_channel; + if (do_set_channel(fd, gbuf, &channel) < 0) + goto fail; + } + + secmode = ((attrp->wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0) ? + attrp->wa_secmode : DLADM_WLAN_SECMODE_NONE; + + if (do_set_encryption(fd, gbuf, &secmode) < 0) + goto fail; + + authmode = ((attrp->wa_valid & DLADM_WLAN_ATTR_AUTH) != 0) ? + attrp->wa_auth : DLADM_WLAN_AUTH_OPEN; + + if (do_set_authmode(fd, gbuf, &authmode) < 0) + goto fail; + + bsstype = ((attrp->wa_valid & DLADM_WLAN_ATTR_BSSTYPE) != 0) ? + attrp->wa_bsstype : DLADM_WLAN_BSSTYPE_BSS; + + if (do_set_bsstype(fd, gbuf, &bsstype) < 0) + goto fail; + + if (secmode == DLADM_WLAN_SECMODE_WEP) { + if (keys == NULL || key_count == 0 || key_count > MAX_NWEPKEYS) + return (DLADM_STATUS_BADARG); + if (do_set_wepkey(fd, gbuf, keys, key_count) < 0) + goto fail; + } + + if (create_ibss) { + if (do_set_channel(fd, gbuf, &channel) < 0) + goto fail; + + if (do_set_createibss(fd, gbuf, &create_ibss) < 0) + goto fail; + + if ((attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) == 0) { + generate_essid(&essid); + essid_valid = B_TRUE; + } + } + + if ((attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) != 0) { + essid = attrp->wa_essid; + essid_valid = B_TRUE; + } + + if (!essid_valid) + return (DLADM_STATUS_FAILED); + if (do_set_essid(fd, gbuf, &essid) < 0) + goto fail; + + start = gethrtime(); + for (;;) { + if (do_get_linkstatus(fd, gbuf) < 0) + goto fail; + + if (IS_CONNECTED(gbuf)) + break; + + (void) poll(NULL, 0, DLADM_WLAN_CONNECT_POLLRATE); + if ((timeout >= 0) && (gethrtime() - start) / + NANOSEC >= timeout) + return (DLADM_STATUS_TIMEDOUT); + } + return (DLADM_STATUS_OK); +fail: + return (dladm_wlan_wlresult2status(gbuf)); +} + +dladm_status_t +dladm_wlan_connect(const char *link, dladm_wlan_attr_t *attrp, + int timeout, void *keys, uint_t key_count, uint_t flags) +{ + int fd, i; + wldp_t *gbuf = NULL; + connect_state_t state = {0, NULL, NULL}; + attr_node_t *nodep = NULL; + boolean_t create_ibss, set_authmode; + dladm_wlan_attr_t **wl_list = NULL; + dladm_status_t status = DLADM_STATUS_FAILED; + + if ((fd = open_link(link)) < 0) + return (DLADM_STATUS_LINKINVAL); + + if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + if (do_get_linkstatus(fd, gbuf) < 0) { + status = DLADM_STATUS_FAILED; + goto done; + } + + if (IS_CONNECTED(gbuf)) { + status = DLADM_STATUS_ISCONN; + goto done; + } + + set_authmode = ((attrp != NULL) && + (attrp->wa_valid & DLADM_WLAN_ATTR_MODE) != 0); + create_ibss = ((flags & DLADM_WLAN_CONNECT_CREATEIBSS) != 0 && + attrp != NULL && + (attrp->wa_valid & DLADM_WLAN_ATTR_BSSTYPE) != 0 && + attrp->wa_bsstype == DLADM_WLAN_BSSTYPE_IBSS); + + if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0 || + (create_ibss && attrp != NULL && + (attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) == 0)) { + status = do_connect(fd, gbuf, attrp, + create_ibss, keys, key_count, timeout); + goto done; + } + + state.cs_attr = attrp; + state.cs_list = NULL; + state.cs_count = 0; + + status = dladm_wlan_scan(link, &state, connect_cb); + if (status != DLADM_STATUS_OK) + goto done; + + if (state.cs_count == 0) { + if (!create_ibss) { + status = DLADM_STATUS_NOTFOUND; + goto done; + } + status = do_connect(fd, gbuf, attrp, create_ibss, + keys, key_count, timeout); + goto done; + } + + wl_list = malloc(state.cs_count * sizeof (dladm_wlan_attr_t *)); + if (wl_list == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + nodep = state.cs_list; + for (i = 0; i < state.cs_count; i++) { + wl_list[i] = &nodep->an_attr; + nodep = nodep->an_next; + } + qsort(wl_list, state.cs_count, sizeof (dladm_wlan_attr_t *), + attr_compare); + + for (i = 0; i < state.cs_count; i++) { + dladm_wlan_attr_t *ap = wl_list[i]; + + status = do_connect(fd, gbuf, ap, create_ibss, keys, + key_count, timeout); + if (status == DLADM_STATUS_OK) + break; + + if (!set_authmode) { + ap->wa_auth = DLADM_WLAN_AUTH_SHARED; + ap->wa_valid |= DLADM_WLAN_ATTR_AUTH; + status = do_connect(fd, gbuf, ap, create_ibss, keys, + key_count, timeout); + if (status == DLADM_STATUS_OK) + break; + } + } +done: + if ((status != DLADM_STATUS_OK) && (status != DLADM_STATUS_ISCONN)) + (void) do_disconnect(fd, gbuf); + + while (state.cs_list != NULL) { + nodep = state.cs_list; + state.cs_list = nodep->an_next; + free(nodep); + } + free(gbuf); + free(wl_list); + (void) close(fd); + return (status); +} + +dladm_status_t +dladm_wlan_disconnect(const char *link) +{ + int fd; + wldp_t *gbuf; + dladm_status_t status; + + if ((fd = open_link(link)) < 0) + return (DLADM_STATUS_BADARG); + + if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + if (do_get_linkstatus(fd, gbuf) < 0) { + status = DLADM_STATUS_FAILED; + goto done; + } + + if (!IS_CONNECTED(gbuf)) { + status = DLADM_STATUS_NOTCONN; + goto done; + } + + if (do_disconnect(fd, gbuf) < 0) { + status = DLADM_STATUS_FAILED; + goto done; + } + + if (do_get_linkstatus(fd, gbuf) < 0) { + status = DLADM_STATUS_FAILED; + goto done; + } + + if (IS_CONNECTED(gbuf)) { + status = DLADM_STATUS_FAILED; + goto done; + } + + status = DLADM_STATUS_OK; +done: + free(gbuf); + (void) close(fd); + return (status); +} + +typedef struct dladm_wlan_linkname { + char wl_name[MAXNAMELEN]; + struct dladm_wlan_linkname *wl_next; +} dladm_wlan_linkname_t; + +typedef struct dladm_wlan_walk { + dladm_wlan_linkname_t *ww_list; + dladm_status_t ww_status; +} dladm_wlan_walk_t; + +/* ARGSUSED */ +static int +append_linkname(di_node_t node, di_minor_t minor, void *arg) +{ + dladm_wlan_walk_t *statep = arg; + dladm_wlan_linkname_t **lastp = &statep->ww_list; + dladm_wlan_linkname_t *wlp = *lastp; + char name[MAXNAMELEN]; + + (void) snprintf(name, MAXNAMELEN, "%s%d", + di_driver_name(node), di_instance(node)); + + while (wlp != NULL) { + if (strcmp(wlp->wl_name, name) == 0) + return (DI_WALK_CONTINUE); + + lastp = &wlp->wl_next; + wlp = wlp->wl_next; + } + if ((wlp = malloc(sizeof (*wlp))) == NULL) { + statep->ww_status = DLADM_STATUS_NOMEM; + return (DI_WALK_CONTINUE); + } + + (void) strlcpy(wlp->wl_name, name, MAXNAMELEN); + wlp->wl_next = NULL; + *lastp = wlp; + + return (DI_WALK_CONTINUE); +} + +dladm_status_t +dladm_wlan_walk(void *arg, boolean_t (*func)(void *, const char *)) +{ + di_node_t root; + dladm_wlan_walk_t state; + dladm_wlan_linkname_t *wlp, *wlp_next; + boolean_t cont = B_TRUE; + + if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) + return (DLADM_STATUS_FAILED); + + state.ww_list = NULL; + state.ww_status = DLADM_STATUS_OK; + (void) di_walk_minor(root, DDI_NT_NET_WIFI, DI_CHECK_ALIAS, + &state, append_linkname); + di_fini(root); + + for (wlp = state.ww_list; wlp != NULL; wlp = wlp_next) { + /* + * NOTE: even if (*func)() returns B_FALSE, the loop continues + * since all memory must be freed. + */ + if (cont) + cont = (*func)(arg, wlp->wl_name); + wlp_next = wlp->wl_next; + free(wlp); + } + return (state.ww_status); +} + +dladm_status_t +dladm_wlan_get_linkattr(const char *link, dladm_wlan_linkattr_t *attrp) +{ + int fd; + wldp_t *gbuf; + wl_rssi_t signal; + wl_bss_type_t bsstype; + wl_authmode_t authmode; + wl_encryption_t encryption; + wl_rates_t *ratesp; + dladm_wlan_attr_t *wl_attrp; + dladm_status_t status = DLADM_STATUS_FAILED; + + if (attrp == NULL) + return (DLADM_STATUS_BADARG); + + if ((fd = open_link(link)) < 0) + return (DLADM_STATUS_LINKINVAL); + + if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + (void) memset(attrp, 0, sizeof (*attrp)); + wl_attrp = &attrp->la_wlan_attr; + + if (do_get_linkstatus(fd, gbuf) < 0) + goto done; + + attrp->la_valid |= DLADM_WLAN_LINKATTR_STATUS; + if (!IS_CONNECTED(gbuf)) { + attrp->la_status = DLADM_WLAN_LINKSTATUS_DISCONNECTED; + status = DLADM_STATUS_OK; + goto done; + } + attrp->la_status = DLADM_WLAN_LINKSTATUS_CONNECTED; + + if (do_get_essid(fd, gbuf) < 0) + goto done; + + (void) strlcpy(wl_attrp->wa_essid.we_bytes, + ((wl_essid_t *)(gbuf->wldp_buf))->wl_essid_essid, + DLADM_WLAN_MAX_ESSID_LEN); + + wl_attrp->wa_valid |= DLADM_WLAN_ATTR_ESSID; + + if (do_get_bssid(fd, gbuf) < 0) + goto done; + + (void) memcpy(wl_attrp->wa_bssid.wb_bytes, gbuf->wldp_buf, + DLADM_WLAN_BSSID_LEN); + + wl_attrp->wa_valid |= DLADM_WLAN_ATTR_BSSID; + + if (do_get_encryption(fd, gbuf) < 0) + goto done; + + encryption = *(wl_encryption_t *)(gbuf->wldp_buf); + wl_attrp->wa_valid |= DLADM_WLAN_ATTR_SECMODE; + + switch (encryption) { + case WL_NOENCRYPTION: + wl_attrp->wa_secmode = DLADM_WLAN_SECMODE_NONE; + break; + case WL_ENC_WEP: + wl_attrp->wa_secmode = DLADM_WLAN_SECMODE_WEP; + break; + default: + wl_attrp->wa_valid &= ~DLADM_WLAN_ATTR_SECMODE; + break; + } + + if (do_get_signal(fd, gbuf) < 0) + goto done; + + signal = *(wl_rssi_t *)(gbuf->wldp_buf); + wl_attrp->wa_valid |= DLADM_WLAN_ATTR_STRENGTH; + wl_attrp->wa_strength = DLADM_WLAN_SIGNAL2STRENGTH(signal); + + if (do_get_rate(fd, gbuf) < 0) + goto done; + + ratesp = (wl_rates_t *)(gbuf->wldp_buf); + if (ratesp->wl_rates_num > 0) { + uint_t i, r = 0; + + for (i = 0; i < ratesp->wl_rates_num; i++) { + if (ratesp->wl_rates_rates[i] > r) + r = ratesp->wl_rates_rates[i]; + } + wl_attrp->wa_speed = r; + wl_attrp->wa_valid |= DLADM_WLAN_ATTR_SPEED; + } + + if (do_get_authmode(fd, gbuf) < 0) + goto done; + + authmode = *(wl_authmode_t *)(gbuf->wldp_buf); + wl_attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH; + + switch (authmode) { + case WL_OPENSYSTEM: + wl_attrp->wa_auth = DLADM_WLAN_AUTH_OPEN; + break; + case WL_SHAREDKEY: + wl_attrp->wa_auth = DLADM_WLAN_AUTH_SHARED; + break; + default: + wl_attrp->wa_valid &= ~DLADM_WLAN_ATTR_AUTH; + break; + } + + if (do_get_bsstype(fd, gbuf) < 0) + goto done; + + bsstype = *(wl_bss_type_t *)(gbuf->wldp_buf); + wl_attrp->wa_valid |= DLADM_WLAN_ATTR_BSSTYPE; + + switch (bsstype) { + case WL_BSS_BSS: + wl_attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_BSS; + break; + case WL_BSS_IBSS: + wl_attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_IBSS; + break; + case WL_BSS_ANY: + wl_attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_ANY; + break; + default: + wl_attrp->wa_valid &= ~DLADM_WLAN_ATTR_BSSTYPE; + break; + } + + if (do_get_mode(fd, gbuf) < 0) + goto done; + + wl_attrp->wa_mode = do_convert_mode((wl_phy_conf_t *)(gbuf->wldp_buf)); + wl_attrp->wa_valid |= DLADM_WLAN_ATTR_MODE; + if (wl_attrp->wa_mode != DLADM_WLAN_MODE_NONE) + wl_attrp->wa_valid |= DLADM_WLAN_ATTR_MODE; + + attrp->la_valid |= DLADM_WLAN_LINKATTR_WLAN; + status = DLADM_STATUS_OK; + +done: + free(gbuf); + (void) close(fd); + return (status); +} + +boolean_t +dladm_wlan_is_valid(const char *link) +{ + int fd = open_link(link); + + if (fd < 0) + return (B_FALSE); + + (void) close(fd); + return (B_TRUE); +} + +/* ARGSUSED */ +static dladm_status_t +do_check_prop(int fd, wldp_t *guf, prop_desc_t *pdp, char **prop_val, + uint_t val_cnt, val_desc_t **vdpp) +{ + int i; + val_desc_t *vdp; + + if (pdp->pd_nmodval == 0) + return (DLADM_STATUS_PROPRDONLY); + + if (val_cnt != 1) + return (DLADM_STATUS_BADVALCNT); + + for (i = 0; i < pdp->pd_nmodval; i++) + if (strcasecmp(*prop_val, pdp->pd_modval[i].vd_name) == 0) + break; + + if (i == pdp->pd_nmodval) + return (DLADM_STATUS_BADVAL); + + vdp = malloc(sizeof (val_desc_t)); + if (vdp == NULL) + return (DLADM_STATUS_NOMEM); + + (void) memcpy(vdp, &pdp->pd_modval[i], sizeof (val_desc_t)); + *vdpp = vdp; + return (DLADM_STATUS_OK); +} + +static dladm_status_t +do_set_prop(int fd, wldp_t *gbuf, prop_desc_t *pdp, + char **prop_val, uint_t val_cnt) +{ + dladm_status_t status; + val_desc_t *vdp = NULL; + uint_t cnt; + + if (pdp->pd_set == NULL) + return (DLADM_STATUS_PROPRDONLY); + + if (prop_val != NULL) { + status = pdp->pd_check(fd, gbuf, pdp, prop_val, + val_cnt, &vdp); + + if (status != DLADM_STATUS_OK) + return (status); + + cnt = val_cnt; + } else { + if (pdp->pd_defval.vd_name == NULL) + return (DLADM_STATUS_NOTSUP); + + if ((vdp = malloc(sizeof (val_desc_t))) == NULL) + return (DLADM_STATUS_NOMEM); + + *vdp = pdp->pd_defval; + cnt = 1; + } + status = pdp->pd_set(fd, gbuf, vdp, cnt); + if (status == DLADM_STATUS_OK) { + /* + * Some ioctls return 0 but store error code in + * wldp_result. Need to fix them. + */ + if (gbuf->wldp_result != WL_SUCCESS) + status = dladm_wlan_wlresult2status(gbuf); + } + free(vdp); + return (status); +} + +dladm_status_t +dladm_wlan_set_prop(const char *link, const char *prop_name, + char **prop_val, uint_t val_cnt, char **errprop) +{ + int fd, i; + wldp_t *gbuf = NULL; + boolean_t found = B_FALSE; + dladm_status_t status = DLADM_STATUS_OK; + + if ((prop_name == NULL && prop_val != NULL) || + (prop_val != NULL && val_cnt == 0)) + return (DLADM_STATUS_BADARG); + + if ((fd = open_link(link)) < 0) + return (DLADM_STATUS_LINKINVAL); + + if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + for (i = 0; i < DLADM_WLAN_MAX_PROPS; i++) { + prop_desc_t *pdp = &prop_table[i]; + dladm_status_t s; + + if (prop_name != NULL && + (strcasecmp(prop_name, pdp->pd_name) != 0)) + continue; + + found = B_TRUE; + s = do_set_prop(fd, gbuf, pdp, prop_val, val_cnt); + + if (prop_name != NULL) { + status = s; + break; + } else { + if (s != DLADM_STATUS_OK && + s != DLADM_STATUS_NOTSUP) { + if (errprop != NULL) + *errprop = pdp->pd_name; + status = s; + break; + } + } + } + if (!found) + status = DLADM_STATUS_NOTFOUND; +done: + free(gbuf); + (void) close(fd); + return (status); +} + +/* ARGSUSED */ +dladm_status_t +dladm_wlan_walk_prop(const char *link, void *arg, + boolean_t (*func)(void *, const char *)) +{ + int i; + + for (i = 0; i < DLADM_WLAN_MAX_PROPS; i++) { + if (!func(arg, prop_table[i].pd_name)) + break; + } + return (DLADM_STATUS_OK); +} + +dladm_status_t +dladm_wlan_get_prop(const char *link, dladm_prop_type_t type, + const char *prop_name, char **prop_val, uint_t *val_cnt) +{ + int fd; + int i; + wldp_t *gbuf; + dladm_status_t status; + uint_t cnt; + prop_desc_t *pdp; + + if (prop_val == NULL || val_cnt == NULL || *val_cnt == 0) + return (DLADM_STATUS_BADARG); + + for (i = 0; i < DLADM_WLAN_MAX_PROPS; i++) + if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) + break; + + if (i == DLADM_WLAN_MAX_PROPS) + return (DLADM_STATUS_NOTFOUND); + + if ((fd = open_link(link)) < 0) + return (DLADM_STATUS_LINKINVAL); + + if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + pdp = &prop_table[i]; + status = DLADM_STATUS_OK; + + switch (type) { + case DLADM_PROP_VAL_CURRENT: + status = pdp->pd_get(fd, gbuf, prop_val, val_cnt); + break; + + case DLADM_PROP_VAL_DEFAULT: + if (pdp->pd_defval.vd_name == NULL) { + status = DLADM_STATUS_NOTSUP; + break; + } + (void) strcpy(*prop_val, pdp->pd_defval.vd_name); + *val_cnt = 1; + break; + + case DLADM_PROP_VAL_MODIFIABLE: + if (pdp->pd_getmod != NULL) { + status = pdp->pd_getmod(fd, gbuf, prop_val, val_cnt); + break; + } + cnt = pdp->pd_nmodval; + if (cnt == 0) { + status = DLADM_STATUS_NOTSUP; + } else if (cnt > *val_cnt) { + status = DLADM_STATUS_TOOSMALL; + } else { + for (i = 0; i < cnt; i++) { + (void) strcpy(prop_val[i], + pdp->pd_modval[i].vd_name); + } + *val_cnt = cnt; + } + break; + default: + status = DLADM_STATUS_BADARG; + break; + } +done: + free(gbuf); + (void) close(fd); + return (status); +} + +static boolean_t +find_val_by_name(const char *str, val_desc_t *vdp, uint_t cnt, uint_t *valp) +{ + int i; + + for (i = 0; i < cnt; i++) { + if (strcasecmp(str, vdp[i].vd_name) == 0) { + *valp = vdp[i].vd_val; + return (B_TRUE); + } + } + return (B_FALSE); +} + +static boolean_t +find_name_by_val(uint_t val, val_desc_t *vdp, uint_t cnt, char **strp) +{ + int i; + + for (i = 0; i < cnt; i++) { + if (val == vdp[i].vd_val) { + *strp = vdp[i].vd_name; + return (B_TRUE); + } + } + return (B_FALSE); +} + +const char * +dladm_wlan_essid2str(dladm_wlan_essid_t *essid, char *buf) +{ + (void) snprintf(buf, DLADM_STRSIZE, "%s", essid->we_bytes); + return (buf); +} + +const char * +dladm_wlan_bssid2str(dladm_wlan_bssid_t *bssid, char *buf) +{ + return (_link_ntoa(bssid->wb_bytes, buf, DLADM_WLAN_BSSID_LEN, + IFT_OTHER)); +} + +static const char * +dladm_wlan_val2str(uint_t val, val_desc_t *vdp, uint_t cnt, char *buf) +{ + char *s; + + if (!find_name_by_val(val, vdp, cnt, &s)) + s = ""; + + (void) snprintf(buf, DLADM_STRSIZE, "%s", s); + return (buf); +} + +const char * +dladm_wlan_secmode2str(dladm_wlan_secmode_t *secmode, char *buf) +{ + return (dladm_wlan_val2str((uint_t)*secmode, secmode_vals, + VALCNT(secmode_vals), buf)); +} + +const char * +dladm_wlan_strength2str(dladm_wlan_strength_t *strength, char *buf) +{ + return (dladm_wlan_val2str((uint_t)*strength, strength_vals, + VALCNT(strength_vals), buf)); +} + +const char * +dladm_wlan_mode2str(dladm_wlan_mode_t *mode, char *buf) +{ + return (dladm_wlan_val2str((uint_t)*mode, mode_vals, + VALCNT(mode_vals), buf)); +} + +const char * +dladm_wlan_speed2str(dladm_wlan_speed_t *speed, char *buf) +{ + (void) snprintf(buf, DLADM_STRSIZE, "%.*f", *speed % 2, + (float)(*speed) / 2); + return (buf); +} + +const char * +dladm_wlan_auth2str(dladm_wlan_auth_t *auth, char *buf) +{ + return (dladm_wlan_val2str((uint_t)*auth, auth_vals, + VALCNT(auth_vals), buf)); +} + +const char * +dladm_wlan_bsstype2str(dladm_wlan_bsstype_t *bsstype, char *buf) +{ + return (dladm_wlan_val2str((uint_t)*bsstype, bsstype_vals, + VALCNT(bsstype_vals), buf)); +} + +const char * +dladm_wlan_linkstatus2str(dladm_wlan_linkstatus_t *linkstatus, char *buf) +{ + return (dladm_wlan_val2str((uint_t)*linkstatus, linkstatus_vals, + VALCNT(linkstatus_vals), buf)); +} + +dladm_status_t +dladm_wlan_str2essid(const char *str, dladm_wlan_essid_t *essid) +{ + if (str[0] == '\0') + return (DLADM_STATUS_BADARG); + + (void) strlcpy(essid->we_bytes, str, DLADM_WLAN_MAX_ESSID_LEN); + return (DLADM_STATUS_OK); +} + +dladm_status_t +dladm_wlan_str2bssid(const char *str, dladm_wlan_bssid_t *bssid) +{ + int len; + uchar_t *buf; + + buf = _link_aton(str, &len); + if (buf == NULL) + return (DLADM_STATUS_BADARG); + + if (len != DLADM_WLAN_BSSID_LEN) { + free(buf); + return (DLADM_STATUS_BADARG); + } + + (void) memcpy(bssid->wb_bytes, buf, len); + free(buf); + return (DLADM_STATUS_OK); +} + +dladm_status_t +dladm_wlan_str2secmode(const char *str, dladm_wlan_secmode_t *secmode) +{ + uint_t val; + + if (!find_val_by_name(str, secmode_vals, VALCNT(secmode_vals), &val)) + return (DLADM_STATUS_BADARG); + + *secmode = (dladm_wlan_secmode_t)val; + return (DLADM_STATUS_OK); +} + +dladm_status_t +dladm_wlan_str2strength(const char *str, dladm_wlan_strength_t *strength) +{ + uint_t val; + + if (!find_val_by_name(str, strength_vals, VALCNT(strength_vals), &val)) + return (DLADM_STATUS_BADARG); + + *strength = (dladm_wlan_strength_t)val; + return (DLADM_STATUS_OK); +} + +dladm_status_t +dladm_wlan_str2mode(const char *str, dladm_wlan_mode_t *mode) +{ + uint_t val; + + if (!find_val_by_name(str, mode_vals, VALCNT(mode_vals), &val)) + return (DLADM_STATUS_BADARG); + + *mode = (dladm_wlan_mode_t)val; + return (DLADM_STATUS_OK); +} + +dladm_status_t +dladm_wlan_str2speed(const char *str, dladm_wlan_speed_t *speed) +{ + *speed = (dladm_wlan_speed_t)(atof(str) * 2); + return (DLADM_STATUS_OK); +} + +dladm_status_t +dladm_wlan_str2auth(const char *str, dladm_wlan_auth_t *auth) +{ + uint_t val; + + if (!find_val_by_name(str, auth_vals, VALCNT(auth_vals), &val)) + return (DLADM_STATUS_BADARG); + + *auth = (dladm_wlan_auth_t)val; + return (DLADM_STATUS_OK); +} + +dladm_status_t +dladm_wlan_str2bsstype(const char *str, dladm_wlan_bsstype_t *bsstype) +{ + uint_t val; + + if (!find_val_by_name(str, bsstype_vals, VALCNT(bsstype_vals), &val)) + return (DLADM_STATUS_BADARG); + + *bsstype = (dladm_wlan_bsstype_t)val; + return (DLADM_STATUS_OK); +} + +dladm_status_t +dladm_wlan_str2linkstatus(const char *str, dladm_wlan_linkstatus_t *linkstatus) +{ + uint_t val; + + if (!find_val_by_name(str, linkstatus_vals, VALCNT(linkstatus_vals), + &val)) + return (DLADM_STATUS_BADARG); + + *linkstatus = (dladm_wlan_linkstatus_t)val; + return (DLADM_STATUS_OK); +} + +static int +do_ioctl(int fd, wldp_t *gbuf, uint_t id, size_t len, uint_t cmd, size_t cmdlen) +{ + int rc; + struct strioctl stri; + + gbuf->wldp_type = NET_802_11; + gbuf->wldp_id = id; + gbuf->wldp_length = len; + + stri.ic_timout = 0; + stri.ic_dp = (char *)gbuf; + stri.ic_cmd = cmd; + stri.ic_len = cmdlen; + + if ((rc = ioctl(fd, I_STR, &stri)) != 0) { + if (rc > 0) + errno = rc; + return (-1); + } + return (0); +} + +static int +do_get_ioctl(int fd, wldp_t *gbuf, uint_t id) +{ + (void) memset(gbuf, 0, MAX_BUF_LEN); + return (do_ioctl(fd, gbuf, id, MAX_BUF_LEN, WLAN_GET_PARAM, + MAX_BUF_LEN)); +} + +static int +do_set_ioctl(int fd, wldp_t *gbuf, uint_t id, void *buf, uint_t buflen) +{ + (void) memset(gbuf, 0, MAX_BUF_LEN); + (void) memcpy(gbuf->wldp_buf, buf, buflen); + buflen += WIFI_BUF_OFFSET; + return (do_ioctl(fd, gbuf, id, buflen, WLAN_SET_PARAM, buflen)); +} + +static int +do_cmd_ioctl(int fd, wldp_t *gbuf, uint_t cmd) +{ + (void) memset(gbuf, 0, MAX_BUF_LEN); + return (do_ioctl(fd, gbuf, cmd, sizeof (wldp_t), WLAN_COMMAND, + sizeof (wldp_t))); +} + +static int +do_scan(int fd, wldp_t *gbuf) +{ + return (do_cmd_ioctl(fd, gbuf, WL_SCAN)); +} + +static int +do_disconnect(int fd, wldp_t *gbuf) +{ + return (do_cmd_ioctl(fd, gbuf, WL_DISASSOCIATE)); +} + +static int +do_get_esslist(int fd, wldp_t *gbuf) +{ + (void) memset(gbuf, 0, MAX_BUF_LEN); + return (do_ioctl(fd, gbuf, WL_ESS_LIST, MAX_BUF_LEN, + WLAN_GET_PARAM, sizeof (wldp_t))); +} + +static int +do_get_bssid(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_BSSID)); +} + +static int +do_get_essid(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_ESSID)); +} + +static int +do_get_bsstype(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_BSS_TYPE)); +} + +static int +do_get_linkstatus(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_LINKSTATUS)); +} + +static int +do_get_rate(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_DESIRED_RATES)); +} + +static int +do_get_phyconf(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_PHY_CONFIG)); +} + +static int +do_get_powermode(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_POWER_MODE)); +} + +static int +do_get_radio(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_RADIO)); +} + +static int +do_get_authmode(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_AUTH_MODE)); +} + +static int +do_get_encryption(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_ENCRYPTION)); +} + +static int +do_get_signal(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_RSSI)); +} + +static int +do_get_mode(int fd, wldp_t *gbuf) +{ + return (do_get_ioctl(fd, gbuf, WL_PHY_CONFIG)); +} + +static dladm_status_t +do_get_rate_common(wldp_t *gbuf, char **prop_val, uint_t *val_cnt) +{ + wl_rates_t *wrp = (wl_rates_t *)gbuf->wldp_buf; + uint_t cnt = wrp->wl_rates_num; + uint_t i; + + if (cnt > *val_cnt) + return (DLADM_STATUS_TOOSMALL); + if (wrp->wl_rates_rates[0] == 0) { + prop_val[0][0] = '\0'; + *val_cnt = 1; + return (DLADM_STATUS_OK); + } + + for (i = 0; i < cnt; i++) { + (void) snprintf(prop_val[i], DLADM_STRSIZE, "%.*f", + wrp->wl_rates_rates[i] % 2, + (float)wrp->wl_rates_rates[i] / 2); + } + *val_cnt = cnt; + return (DLADM_STATUS_OK); +} + +static dladm_status_t +do_get_rate_prop(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) +{ + if (do_get_rate(fd, gbuf) < 0) + return (dladm_wlan_wlresult2status(gbuf)); + + return (do_get_rate_common(gbuf, prop_val, val_cnt)); +} + +static dladm_status_t +do_get_rate_mod(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) +{ + if (do_get_ioctl(fd, gbuf, WL_SUPPORTED_RATES) < 0) + return (DLADM_STATUS_FAILED); + + return (do_get_rate_common(gbuf, prop_val, val_cnt)); +} + +static dladm_status_t +do_get_channel_prop(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) +{ + uint32_t channel; + + if (do_get_phyconf(fd, gbuf) < 0) + return (dladm_wlan_wlresult2status(gbuf)); + + if (!do_convert_chan((wl_phy_conf_t *)gbuf->wldp_buf, &channel)) + return (DLADM_STATUS_NOTFOUND); + + (void) snprintf(*prop_val, DLADM_STRSIZE, "%u", channel); + *val_cnt = 1; + + return (DLADM_STATUS_OK); +} + +static dladm_status_t +do_get_powermode_prop(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) +{ + wl_ps_mode_t *mode; + const char *s; + + if (do_get_powermode(fd, gbuf) < 0) + return (dladm_wlan_wlresult2status(gbuf)); + + mode = (wl_ps_mode_t *)(gbuf->wldp_buf); + switch (mode->wl_ps_mode) { + case WL_PM_AM: + s = "off"; + break; + case WL_PM_MPS: + s = "max"; + break; + case WL_PM_FAST: + s = "fast"; + break; + default: + return (DLADM_STATUS_NOTFOUND); + } + (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); + *val_cnt = 1; + + return (DLADM_STATUS_OK); +} + +static dladm_status_t +do_get_radio_prop(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) +{ + wl_radio_t radio; + const char *s; + + if (do_get_radio(fd, gbuf) < 0) + return (dladm_wlan_wlresult2status(gbuf)); + + radio = *(wl_radio_t *)(gbuf->wldp_buf); + switch (radio) { + case B_TRUE: + s = "on"; + break; + case B_FALSE: + s = "off"; + break; + default: + return (DLADM_STATUS_NOTFOUND); + } + (void) snprintf(*prop_val, DLADM_STRSIZE, "%s", s); + *val_cnt = 1; + + return (DLADM_STATUS_OK); +} + +static int +do_set_bsstype(int fd, wldp_t *gbuf, dladm_wlan_bsstype_t *bsstype) +{ + wl_bss_type_t ibsstype; + + switch (*bsstype) { + case DLADM_WLAN_BSSTYPE_BSS: + ibsstype = WL_BSS_BSS; + break; + case DLADM_WLAN_BSSTYPE_IBSS: + ibsstype = WL_BSS_IBSS; + break; + default: + ibsstype = WL_BSS_ANY; + break; + } + return (do_set_ioctl(fd, gbuf, WL_BSS_TYPE, &ibsstype, + sizeof (ibsstype))); +} + +static int +do_set_authmode(int fd, wldp_t *gbuf, dladm_wlan_auth_t *auth) +{ + wl_authmode_t auth_mode; + + switch (*auth) { + case DLADM_WLAN_AUTH_OPEN: + auth_mode = WL_OPENSYSTEM; + break; + case DLADM_WLAN_AUTH_SHARED: + auth_mode = WL_SHAREDKEY; + break; + default: + return (-1); + } + return (do_set_ioctl(fd, gbuf, WL_AUTH_MODE, &auth_mode, + sizeof (auth_mode))); +} + +static int +do_set_encryption(int fd, wldp_t *gbuf, dladm_wlan_secmode_t *secmode) +{ + wl_encryption_t encryption; + + switch (*secmode) { + case DLADM_WLAN_SECMODE_NONE: + encryption = WL_NOENCRYPTION; + break; + case DLADM_WLAN_SECMODE_WEP: + encryption = WL_ENC_WEP; + break; + default: + return (-1); + } + return (do_set_ioctl(fd, gbuf, WL_ENCRYPTION, &encryption, + sizeof (encryption))); +} + +static int +do_set_wepkey(int fd, wldp_t *gbuf, dladm_wlan_wepkey_t *keys, + uint_t key_count) +{ + int i; + wl_wep_key_t *wkp; + wl_wep_key_tab_t wepkey_tab; + dladm_wlan_wepkey_t *kp; + + if (key_count == 0 || key_count > MAX_NWEPKEYS || keys == NULL) + return (-1); + + (void) memset(wepkey_tab, 0, sizeof (wepkey_tab)); + for (i = 0; i < MAX_NWEPKEYS; i++) + wepkey_tab[i].wl_wep_operation = WL_NUL; + + for (i = 0; i < key_count; i++) { + kp = &keys[i]; + if (kp->wk_idx == 0 || kp->wk_idx > MAX_NWEPKEYS) + return (-1); + if (kp->wk_len != DLADM_WLAN_WEPKEY64_LEN && + kp->wk_len != DLADM_WLAN_WEPKEY128_LEN) + return (-1); + + wkp = &wepkey_tab[kp->wk_idx - 1]; + wkp->wl_wep_operation = WL_ADD; + wkp->wl_wep_length = kp->wk_len; + (void) memcpy(wkp->wl_wep_key, kp->wk_val, kp->wk_len); + } + + return (do_set_ioctl(fd, gbuf, WL_WEP_KEY_TAB, &wepkey_tab, + sizeof (wepkey_tab))); +} + +static int +do_set_essid(int fd, wldp_t *gbuf, dladm_wlan_essid_t *essid) +{ + wl_essid_t iessid; + + (void) memset(&iessid, 0, sizeof (essid)); + + if (essid != NULL && essid->we_bytes[0] != '\0') { + iessid.wl_essid_length = strlen(essid->we_bytes); + (void) strlcpy(iessid.wl_essid_essid, essid->we_bytes, + sizeof (iessid.wl_essid_essid)); + } else { + return (-1); + } + return (do_set_ioctl(fd, gbuf, WL_ESSID, &iessid, sizeof (iessid))); +} + +/* ARGSUSED */ +static dladm_status_t +do_check_rate(int fd, wldp_t *gbuf, prop_desc_t *pdp, char **prop_val, + uint_t val_cnt, val_desc_t **vdpp) +{ + int i; + uint_t modval_cnt = MAX_SUPPORT_RATES; + char *buf, **modval; + dladm_status_t status; + val_desc_t *vdp = NULL; + + if (val_cnt != 1) + return (DLADM_STATUS_BADVALCNT); + + buf = malloc((sizeof (char *) + DLADM_STRSIZE) * MAX_SUPPORT_RATES); + if (buf == NULL) + goto done; + + modval = (char **)(void *)buf; + for (i = 0; i < MAX_SUPPORT_RATES; i++) { + modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + + i * DLADM_STRSIZE; + } + + status = do_get_rate_mod(fd, gbuf, modval, &modval_cnt); + if (status != DLADM_STATUS_OK) + goto done; + + vdp = malloc(sizeof (val_desc_t)); + if (vdp == NULL) { + status = DLADM_STATUS_NOMEM; + goto done; + } + + for (i = 0; i < modval_cnt; i++) { + if (strcasecmp(*prop_val, modval[i]) == 0) { + vdp->vd_val = (uint_t)(atof(*prop_val) * 2); + status = DLADM_STATUS_OK; + *vdpp = vdp; + vdp = NULL; + break; + } + } + if (i == modval_cnt) + status = DLADM_STATUS_BADVAL; +done: + free(buf); + free(vdp); + return (status); +} + +static dladm_status_t +do_set_rate_prop(int fd, wldp_t *gbuf, val_desc_t *vdp, uint_t val_cnt) +{ + dladm_wlan_rates_t rates; + + if (val_cnt != 1) + return (DLADM_STATUS_BADVALCNT); + + rates.wr_cnt = 1; + rates.wr_rates[0] = vdp[0].vd_val; + + if (do_set_rate(fd, gbuf, &rates) < 0) + return (dladm_wlan_wlresult2status(gbuf)); + + return (DLADM_STATUS_OK); +} + +static int +do_set_rate(int fd, wldp_t *gbuf, dladm_wlan_rates_t *rates) +{ + int i; + uint_t len; + wl_rates_t *wrp = (wl_rates_t *)gbuf->wldp_buf; + + (void) memset(gbuf, 0, MAX_BUF_LEN); + + for (i = 0; i < rates->wr_cnt; i++) + wrp->wl_rates_rates[i] = rates->wr_rates[i]; + wrp->wl_rates_num = rates->wr_cnt; + + len = offsetof(wl_rates_t, wl_rates_rates) + + (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; + return (do_ioctl(fd, gbuf, WL_DESIRED_RATES, len, WLAN_SET_PARAM, len)); +} + +/* ARGSUSED */ +static dladm_status_t +do_set_powermode_prop(int fd, wldp_t *gbuf, val_desc_t *vdp, uint_t val_cnt) +{ + dladm_wlan_powermode_t powermode = (dladm_wlan_powermode_t)vdp->vd_val; + + if (do_set_powermode(fd, gbuf, &powermode) < 0) + return (dladm_wlan_wlresult2status(gbuf)); + + return (DLADM_STATUS_OK); +} + +static int +do_set_powermode(int fd, wldp_t *gbuf, dladm_wlan_powermode_t *pm) +{ + wl_ps_mode_t ps_mode; + + (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); + + switch (*pm) { + case DLADM_WLAN_PM_OFF: + ps_mode.wl_ps_mode = WL_PM_AM; + break; + case DLADM_WLAN_PM_MAX: + ps_mode.wl_ps_mode = WL_PM_MPS; + break; + case DLADM_WLAN_PM_FAST: + ps_mode.wl_ps_mode = WL_PM_FAST; + break; + default: + return (-1); + } + return (do_set_ioctl(fd, gbuf, WL_POWER_MODE, &ps_mode, + sizeof (ps_mode))); +} + +/* ARGSUSED */ +static dladm_status_t +do_set_radio_prop(int fd, wldp_t *gbuf, val_desc_t *vdp, uint_t val_cnt) +{ + dladm_wlan_radio_t radio = (dladm_wlan_radio_t)vdp->vd_val; + + if (do_set_radio(fd, gbuf, &radio) < 0) + return (dladm_wlan_wlresult2status(gbuf)); + + return (DLADM_STATUS_OK); +} + +static int +do_set_radio(int fd, wldp_t *gbuf, dladm_wlan_radio_t *radio) +{ + wl_radio_t r; + + switch (*radio) { + case DLADM_WLAN_RADIO_ON: + r = B_TRUE; + break; + case DLADM_WLAN_RADIO_OFF: + r = B_FALSE; + break; + default: + return (-1); + } + return (do_set_ioctl(fd, gbuf, WL_RADIO, &r, sizeof (r))); +} + +static int +do_set_channel(int fd, wldp_t *gbuf, dladm_wlan_channel_t *channel) +{ + wl_phy_conf_t phy_conf; + + if (*channel > MAX_CHANNEL_NUM) + return (-1); + + (void) memset(&phy_conf, 0xff, sizeof (phy_conf)); + phy_conf.wl_phy_dsss_conf.wl_dsss_channel = *channel; + + return (do_set_ioctl(fd, gbuf, WL_PHY_CONFIG, &phy_conf, + sizeof (phy_conf))); +} + +static int +do_set_createibss(int fd, wldp_t *gbuf, boolean_t *create_ibss) +{ + wl_create_ibss_t cr = (wl_create_ibss_t)(*create_ibss); + + return (do_set_ioctl(fd, gbuf, WL_CREATE_IBSS, &cr, sizeof (cr))); +} + +static void +generate_essid(dladm_wlan_essid_t *essid) +{ + srandom(gethrtime()); + (void) snprintf(essid->we_bytes, DLADM_WLAN_MAX_ESSID_LEN, "%d", + random()); +} diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/libdlwlan.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libdladm/common/libdlwlan.h Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,202 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LIBDLWLAN_H +#define _LIBDLWLAN_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file includes structures, macros and routines used by WLAN link + * administration. + */ + +#include +#include + +/* + * General libdlwlan definitions and functions. + * + * These interfaces are ON consolidation-private. + * For documentation, refer to PSARC/2006/623. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define DLADM_WLAN_MAX_ESSID_LEN 32 /* per 802.11 spec */ +#define DLADM_WLAN_BSSID_LEN 6 /* per 802.11 spec */ + +#define DLADM_WLAN_CONNECT_TIMEOUT_DEFAULT 10 +#define DLADM_WLAN_CONNECT_CREATEIBSS 0x00000001 +#define DLADM_WLAN_CONNECT_NOSCAN 0x00000002 + +typedef struct dladm_wlan_essid { + char we_bytes[DLADM_WLAN_MAX_ESSID_LEN]; +} dladm_wlan_essid_t; + +typedef struct dladm_wlan_bssid { + uint8_t wb_bytes[DLADM_WLAN_BSSID_LEN]; +} dladm_wlan_bssid_t; + +typedef enum { + DLADM_WLAN_SECMODE_NONE = 1, + DLADM_WLAN_SECMODE_WEP +} dladm_wlan_secmode_t; + +typedef enum { + DLADM_WLAN_STRENGTH_VERY_WEAK = 1, + DLADM_WLAN_STRENGTH_WEAK, + DLADM_WLAN_STRENGTH_GOOD, + DLADM_WLAN_STRENGTH_VERY_GOOD, + DLADM_WLAN_STRENGTH_EXCELLENT +} dladm_wlan_strength_t; + +typedef enum { + DLADM_WLAN_MODE_NONE = 0, + DLADM_WLAN_MODE_80211A, + DLADM_WLAN_MODE_80211B, + DLADM_WLAN_MODE_80211G +} dladm_wlan_mode_t; + +typedef enum { + DLADM_WLAN_AUTH_OPEN = 1, + DLADM_WLAN_AUTH_SHARED +} dladm_wlan_auth_t; + +typedef enum { + DLADM_WLAN_BSSTYPE_BSS = 1, + DLADM_WLAN_BSSTYPE_IBSS, + DLADM_WLAN_BSSTYPE_ANY +} dladm_wlan_bsstype_t; + +typedef enum { + DLADM_WLAN_LINKSTATUS_DISCONNECTED = 1, + DLADM_WLAN_LINKSTATUS_CONNECTED +} dladm_wlan_linkstatus_t; + +typedef uint32_t dladm_wlan_speed_t; +typedef uint32_t dladm_wlan_channel_t; + +enum { + DLADM_WLAN_ATTR_ESSID = 0x00000001, + DLADM_WLAN_ATTR_BSSID = 0x00000002, + DLADM_WLAN_ATTR_SECMODE = 0x00000004, + DLADM_WLAN_ATTR_STRENGTH = 0x00000008, + DLADM_WLAN_ATTR_MODE = 0x00000010, + DLADM_WLAN_ATTR_SPEED = 0x00000020, + DLADM_WLAN_ATTR_AUTH = 0x00000040, + DLADM_WLAN_ATTR_BSSTYPE = 0x00000080, + DLADM_WLAN_ATTR_CHANNEL = 0x00000100 +}; +typedef struct dladm_wlan_attr { + uint_t wa_valid; + dladm_wlan_essid_t wa_essid; + dladm_wlan_bssid_t wa_bssid; + dladm_wlan_secmode_t wa_secmode; + dladm_wlan_strength_t wa_strength; + dladm_wlan_mode_t wa_mode; + dladm_wlan_speed_t wa_speed; + dladm_wlan_auth_t wa_auth; + dladm_wlan_bsstype_t wa_bsstype; + dladm_wlan_channel_t wa_channel; +} dladm_wlan_attr_t; + +enum { + DLADM_WLAN_LINKATTR_STATUS = 0x00000001, + DLADM_WLAN_LINKATTR_WLAN = 0x00000002 +}; +typedef struct dladm_wlan_linkattr { + uint_t la_valid; + dladm_wlan_linkstatus_t la_status; + dladm_wlan_attr_t la_wlan_attr; +} dladm_wlan_linkattr_t; + +#define DLADM_WLAN_WEPKEY64_LEN 5 /* per WEP spec */ +#define DLADM_WLAN_WEPKEY128_LEN 13 /* per WEP spec */ +#define DLADM_WLAN_MAX_WEPKEY_LEN 13 /* per WEP spec */ +#define DLADM_WLAN_MAX_WEPKEYS 4 /* MAX_NWEPKEYS */ +#define DLADM_WLAN_MAX_WEPKEYNAME_LEN 64 +typedef struct dladm_wlan_wepkey { + uint_t wk_idx; + uint_t wk_len; + uint8_t wk_val[DLADM_WLAN_MAX_WEPKEY_LEN]; + char wk_name[DLADM_WLAN_MAX_WEPKEYNAME_LEN]; +} dladm_wlan_wepkey_t; + +extern dladm_status_t dladm_wlan_scan(const char *, void *, + boolean_t (*)(void *, dladm_wlan_attr_t *)); +extern dladm_status_t dladm_wlan_connect(const char *, dladm_wlan_attr_t *, + int, void *, uint_t, uint_t); +extern dladm_status_t dladm_wlan_disconnect(const char *); +extern dladm_status_t dladm_wlan_get_linkattr(const char *, + dladm_wlan_linkattr_t *); +extern dladm_status_t dladm_wlan_walk(void *, + boolean_t (*)(void *, const char *)); +extern boolean_t dladm_wlan_is_valid(const char *); +extern dladm_status_t dladm_wlan_set_prop(const char *, const char *, + char **, uint_t, char **); +extern dladm_status_t dladm_wlan_walk_prop(const char *, void *, + boolean_t (*)(void *, const char *)); +extern dladm_status_t dladm_wlan_get_prop(const char *, dladm_prop_type_t, + const char *, char **, uint_t *); + +extern const char *dladm_wlan_essid2str(dladm_wlan_essid_t *, char *); +extern const char *dladm_wlan_bssid2str(dladm_wlan_bssid_t *, char *); +extern const char *dladm_wlan_secmode2str(dladm_wlan_secmode_t *, char *); +extern const char *dladm_wlan_strength2str(dladm_wlan_strength_t *, + char *); +extern const char *dladm_wlan_mode2str(dladm_wlan_mode_t *, char *); +extern const char *dladm_wlan_speed2str(dladm_wlan_speed_t *, char *); +extern const char *dladm_wlan_auth2str(dladm_wlan_auth_t *, char *); +extern const char *dladm_wlan_bsstype2str(dladm_wlan_bsstype_t *, char *); +extern const char *dladm_wlan_linkstatus2str(dladm_wlan_linkstatus_t *, + char *); + +extern dladm_status_t dladm_wlan_str2essid(const char *, + dladm_wlan_essid_t *); +extern dladm_status_t dladm_wlan_str2bssid(const char *, + dladm_wlan_bssid_t *); +extern dladm_status_t dladm_wlan_str2secmode(const char *, + dladm_wlan_secmode_t *); +extern dladm_status_t dladm_wlan_str2strength(const char *, + dladm_wlan_strength_t *); +extern dladm_status_t dladm_wlan_str2mode(const char *, + dladm_wlan_mode_t *); +extern dladm_status_t dladm_wlan_str2speed(const char *, + dladm_wlan_speed_t *); +extern dladm_status_t dladm_wlan_str2auth(const char *, + dladm_wlan_auth_t *); +extern dladm_status_t dladm_wlan_str2bsstype(const char *, + dladm_wlan_bsstype_t *); +extern dladm_status_t dladm_wlan_str2linkstatus(const char *, + dladm_wlan_linkstatus_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBDLWLAN_H */ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/libdlwlan_impl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libdladm/common/libdlwlan_impl.h Wed Mar 21 09:48:58 2007 -0700 @@ -0,0 +1,83 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LIBDLWLAN_IMPL_H +#define _LIBDLWLAN_IMPL_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include +#include + +/* + * Implementation-private data structures, macros, and constants. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Map a signal value from 0-15 into an enumerated strength. Since there are + * 5 strengths but 16 values, by convention the "middle" strength gets the + * extra value. Thus, the buckets are 0-2, 3-5, 6-9, 10-12, and 13-15. + */ +#define DLADM_WLAN_SIGNAL2STRENGTH(signal) \ + (((signal) > 12 ? DLADM_WLAN_STRENGTH_EXCELLENT : \ + ((signal) > 9 ? DLADM_WLAN_STRENGTH_VERY_GOOD : \ + ((signal) > 5 ? DLADM_WLAN_STRENGTH_GOOD : \ + ((signal) > 2 ? DLADM_WLAN_STRENGTH_WEAK : \ + DLADM_WLAN_STRENGTH_VERY_WEAK))))) + +/* + * Convert between an OFDM MHz and a channel number. + */ +#define DLADM_WLAN_OFDM2CHAN(mhz) (((mhz) - 5000) / 5) + +#define DLADM_WLAN_CONNECT_POLLRATE 200 /* milliseconds */ +#define DLADM_WLAN_CONNECT_DEFAULT_CHANNEL 1 + +#define DLADM_WLAN_MAX_RATES 4 +typedef struct dladm_wlan_rates { + uint8_t wr_rates[DLADM_WLAN_MAX_RATES]; + int wr_cnt; +} dladm_wlan_rates_t; + +typedef enum { + DLADM_WLAN_RADIO_ON = 1, + DLADM_WLAN_RADIO_OFF +} dladm_wlan_radio_t; + +typedef enum { + DLADM_WLAN_PM_OFF = 1, + DLADM_WLAN_PM_MAX, + DLADM_WLAN_PM_FAST +} dladm_wlan_powermode_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBDLWLAN_IMPL_H */ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/linkprop.c --- a/usr/src/lib/libdladm/common/linkprop.c Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/lib/libdladm/common/linkprop.c Wed Mar 21 09:48:58 2007 -0700 @@ -37,9 +37,9 @@ #include #include #include -#include +#include #include - +#include #include #include @@ -90,45 +90,6 @@ #define MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) -/* - * Convert a wladm_status_t to a dladm_status_t. This is used by wrappers - * to libwladm routines (e.g. dladm_set_prop()). Note that the mapping is - * not 1-1; whenever possible we try to look for an error code with a - * similar meaning. Error codes with no suitable counterpart in libdladm - * will be mapped to DLADM_STATUS_FAILED. Clients who require clearer error - * reporting should use libwladm directly. - */ -static dladm_status_t -dladm_wladmstatus2status(wladm_status_t wstatus) -{ - switch (wstatus) { - case WLADM_STATUS_OK: - return (DLADM_STATUS_OK); - case WLADM_STATUS_FAILED: - return (DLADM_STATUS_FAILED); - case WLADM_STATUS_NOTSUP: - return (DLADM_STATUS_NOTSUP); - case WLADM_STATUS_BADARG: - return (DLADM_STATUS_BADARG); - case WLADM_STATUS_NOTFOUND: - return (DLADM_STATUS_NOTFOUND); - case WLADM_STATUS_BADVAL: - return (DLADM_STATUS_BADVAL); - case WLADM_STATUS_LINKINVAL: - return (DLADM_STATUS_LINKINVAL); - case WLADM_STATUS_NOMEM: - return (DLADM_STATUS_NOMEM); - case WLADM_STATUS_PROPRDONLY: - return (DLADM_STATUS_PROPRDONLY); - case WLADM_STATUS_TOOSMALL: - return (DLADM_STATUS_TOOSMALL); - case WLADM_STATUS_BADVALCNT: - return (DLADM_STATUS_BADVALCNT); - default: - return (DLADM_STATUS_FAILED); - } -} - dladm_status_t dladm_set_prop(const char *link, const char *prop_name, char **prop_val, uint_t val_cnt, uint_t flags, char **errprop) @@ -148,10 +109,9 @@ if (status == DLADM_STATUS_NOTFOUND) { status = DLADM_STATUS_BADARG; - if (wladm_is_valid(link)) { - status = dladm_wladmstatus2status( - wladm_set_prop(link, prop_name, - prop_val, val_cnt, errprop)); + if (dladm_wlan_is_valid(link)) { + status = dladm_wlan_set_prop(link, prop_name, + prop_val, val_cnt, errprop); } } if (status != DLADM_STATUS_OK) @@ -177,11 +137,10 @@ return (DLADM_STATUS_BADARG); /* For wifi links, show wifi properties first */ - if (wladm_is_valid(link)) { + if (dladm_wlan_is_valid(link)) { dladm_status_t status; - status = dladm_wladmstatus2status( - wladm_walk_prop(link, arg, func)); + status = dladm_wlan_walk_prop(link, arg, func); if (status != DLADM_STATUS_OK) return (status); } @@ -205,6 +164,8 @@ return (DLADM_STATUS_BADARG); if (type == DLADM_PROP_VAL_PERSISTENT) { + if (i_dladm_is_prop_temponly(prop_name, NULL)) + return (DLADM_STATUS_TEMPONLY); return (i_dladm_get_prop_db(link, prop_name, prop_val, val_cntp)); } @@ -214,26 +175,9 @@ if (status != DLADM_STATUS_NOTFOUND) return (status); - if (wladm_is_valid(link)) { - wladm_prop_type_t wtype; - - switch (type) { - case DLADM_PROP_VAL_CURRENT: - wtype = WLADM_PROP_VAL_CURRENT; - break; - case DLADM_PROP_VAL_DEFAULT: - wtype = WLADM_PROP_VAL_DEFAULT; - break; - case DLADM_PROP_VAL_MODIFIABLE: - wtype = WLADM_PROP_VAL_MODIFIABLE; - break; - default: - return (DLADM_STATUS_BADARG); - } - - return (dladm_wladmstatus2status( - wladm_get_prop(link, wtype, prop_name, - prop_val, val_cntp))); + if (dladm_wlan_is_valid(link)) { + return (dladm_wlan_get_prop(link, type, prop_name, + prop_val, val_cntp)); } return (DLADM_STATUS_BADARG); } @@ -1195,9 +1139,3 @@ return (B_FALSE); } - -boolean_t -dladm_is_prop_temponly(const char *prop_name, char **errprop) -{ - return (i_dladm_is_prop_temponly(prop_name, errprop)); -} diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/llib-ldladm --- a/usr/src/lib/libdladm/common/llib-ldladm Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/lib/libdladm/common/llib-ldladm Wed Mar 21 09:48:58 2007 -0700 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,4 +28,6 @@ /*LINTLIBRARY*/ /*PROTOLIB1*/ -#include +#include +#include +#include diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/mapfile-vers --- a/usr/src/lib/libdladm/common/mapfile-vers Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/lib/libdladm/common/mapfile-vers Wed Mar 21 09:48:58 2007 -0700 @@ -29,24 +29,69 @@ global: dladm_info; dladm_walk; - dladm_walk_vlan; + dladm_hold_link; + dladm_rele_link; + dladm_status2str; + dladm_linkstate2str; + dladm_linkduplex2str; + dladm_set_rootdir; + dladm_mac_walk; + dladm_init_linkprop; dladm_get_prop; dladm_set_prop; dladm_walk_prop; - dladm_is_prop_temponly; + dladm_init_secobj; dladm_get_secobj; dladm_set_secobj; dladm_unset_secobj; dladm_walk_secobj; - dladm_status2str; dladm_secobjclass2str; dladm_str2secobjclass; - dladm_init_linkprop; - dladm_init_secobj; - dladm_set_rootdir; + dladm_aggr_walk; + dladm_aggr_up; + dladm_aggr_down; + dladm_aggr_add; + dladm_aggr_create; + dladm_aggr_delete; + dladm_aggr_modify; + dladm_aggr_remove; + dladm_aggr_lacpmode2str; + dladm_aggr_lacptimer2str; + dladm_aggr_macaddr2str; + dladm_aggr_policy2str; + dladm_aggr_portstate2str; + dladm_aggr_str2lacpmode; + dladm_aggr_str2lacptimer; + dladm_aggr_str2macaddr; + dladm_aggr_str2policy; + dladm_wlan_walk; + dladm_wlan_scan; + dladm_wlan_connect; + dladm_wlan_disconnect; + dladm_wlan_get_linkattr; + dladm_wlan_is_valid; + dladm_wlan_set_prop; + dladm_wlan_walk_prop; + dladm_wlan_get_prop; + dladm_wlan_essid2str; + dladm_wlan_bssid2str; + dladm_wlan_secmode2str; + dladm_wlan_strength2str; + dladm_wlan_mode2str; + dladm_wlan_speed2str; + dladm_wlan_auth2str; + dladm_wlan_bsstype2str; + dladm_wlan_linkstatus2str; + dladm_wlan_str2essid; + dladm_wlan_str2bssid; + dladm_wlan_str2secmode; + dladm_wlan_str2strength; + dladm_wlan_str2mode; + dladm_wlan_str2speed; + dladm_wlan_str2auth; + dladm_wlan_str2bsstype; + dladm_wlan_str2linkstatus; - dladm_hold_link; - dladm_rele_link; local: *; }; diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libdladm/common/secobj.c --- a/usr/src/lib/libdladm/common/secobj.c Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/lib/libdladm/common/secobj.c Wed Mar 21 09:48:58 2007 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -34,6 +34,7 @@ #include #include #include +#include #include static dladm_status_t i_dladm_set_secobj_db(const char *, diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/liblaadm/Makefile --- a/usr/src/lib/liblaadm/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include $(SRC)/lib/Makefile.lib - -HDRS = liblaadm.h -HDRDIR = common - -SUBDIRS = $(MACH) - -POFILE = liblaadm.po -MSGFILES = common/liblaadm.c - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint - -.KEEP_STATE: - -all clean clobber install lint: $(SUBDIRS) - -install_h: $(ROOTHDRS) - -check: $(CHECKHDRS) - -$(POFILE): pofile_MSGFILES - -_msg: $(MSGDOMAINPOFILE) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include $(SRC)/Makefile.msg.targ -include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/liblaadm/Makefile.com --- a/usr/src/lib/liblaadm/Makefile.com Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -LIBRARY = liblaadm.a -VERS = .1 -OBJECTS = liblaadm.o - -include ../../Makefile.lib - -# install this library in the root filesystem -include ../../Makefile.rootfs - -LIBS = $(DYNLIB) $(LINTLIB) - -LDLIBS += -lsocket -lc - -SRCDIR = ../common -$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) -D_REENTRANT - -.KEEP_STATE: - -all: $(LIBS) - -lint: lintcheck - -include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/liblaadm/common/liblaadm.c --- a/usr/src/lib/liblaadm/common/liblaadm.c Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1707 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Link Aggregation Administration Library. - * - * This library is used by administration tools such as dladm(1M) to - * configure link aggregations. - * - * Link aggregation configuration information is saved in a text - * file of the following format: - * - * ::= * - * ::= - * - * ::= ' ' | '\t' - * ::= - * ::= - * ::= * - * ::= ',' - * ::= - * ::= - * ::= - * ::= * - * ::= ',' - * ::= 'L2' | 'L3' | 'L4' - * ::= 'auto' | - * ::= ':' ':' ':' ':' ':' - * ::= 'off' | 'active' | 'passive' - * ::= 'short' | 'long' - */ - -#define LAADM_DEV "/devices/pseudo/aggr@0:" AGGR_DEVNAME_CTL -#define LAADM_DB "/etc/dladm/aggregation.conf" -#define LAADM_DB_TMP "/etc/dladm/aggregation.conf.new" -#define LAADM_DB_LOCK "/tmp/aggregation.conf.lock" - -#define LAADM_DB_PERMS S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH -#define LAADM_DB_OWNER 15 /* "dladm" UID */ -#define LAADM_DB_GROUP 3 /* "sys" GID */ - -/* - * The largest configurable aggregation key. Because by default the key is - * used as the DLPI device PPA and default VLAN PPA's are calculated as - * ((1000 * vid) + PPA), the largest key can't be > 999. - */ -#define LAADM_MAX_KEY 999 - -#define BLANK_LINE(s) ((s[0] == '\0') || (s[0] == '#') || (s[0] == '\n')) - -#define MAXLINELEN 1024 - -/* Limits on buffer size for LAIOC_INFO request */ -#define MIN_INFO_SIZE (4*1024) -#define MAX_INFO_SIZE (128*1024) - -#define MAXPATHLEN 1024 - -static uchar_t zero_mac[] = {0, 0, 0, 0, 0, 0}; - -/* configuration database entry */ -typedef struct laadm_grp_attr_db { - uint32_t lt_key; - uint32_t lt_policy; - uint32_t lt_nports; - laadm_port_attr_db_t *lt_ports; - boolean_t lt_mac_fixed; - uchar_t lt_mac[ETHERADDRL]; - aggr_lacp_mode_t lt_lacp_mode; - aggr_lacp_timer_t lt_lacp_timer; -} laadm_grp_attr_db_t; - -typedef struct laadm_up { - uint32_t lu_key; - boolean_t lu_found; - int lu_fd; -} laadm_up_t; - -typedef struct laadm_down { - uint32_t ld_key; - boolean_t ld_found; -} laadm_down_t; - -typedef struct laadm_modify_attr { - uint32_t ld_policy; - boolean_t ld_mac_fixed; - uchar_t ld_mac[ETHERADDRL]; - aggr_lacp_mode_t ld_lacp_mode; - aggr_lacp_timer_t ld_lacp_timer; -} laadm_modify_attr_t; - -typedef struct policy_s { - char *pol_name; - uint32_t policy; -} policy_t; - -static policy_t policies[] = { - {"L2", AGGR_POLICY_L2}, - {"L3", AGGR_POLICY_L3}, - {"L4", AGGR_POLICY_L4}}; - -#define NPOLICIES (sizeof (policies) / sizeof (policy_t)) - -typedef struct laadm_lacp_mode_s { - char *mode_str; - aggr_lacp_mode_t mode_id; -} laadm_lacp_mode_t; - -static laadm_lacp_mode_t lacp_modes[] = { - {"off", AGGR_LACP_OFF}, - {"active", AGGR_LACP_ACTIVE}, - {"passive", AGGR_LACP_PASSIVE}}; - -#define NLACP_MODES (sizeof (lacp_modes) / sizeof (laadm_lacp_mode_t)) - -typedef struct laadm_lacp_timer_s { - char *lt_str; - aggr_lacp_timer_t lt_id; -} laadm_lacp_timer_t; - -static laadm_lacp_timer_t lacp_timers[] = { - {"short", AGGR_LACP_TIMER_SHORT}, - {"long", AGGR_LACP_TIMER_LONG}}; - -#define NLACP_TIMERS (sizeof (lacp_timers) / sizeof (laadm_lacp_timer_t)) - -typedef struct delete_db_state { - uint32_t ds_key; - boolean_t ds_found; -} delete_db_state_t; - - -typedef struct modify_db_state { - uint32_t us_key; - uint32_t us_mask; - laadm_modify_attr_t *us_attr_new; - laadm_modify_attr_t *us_attr_old; - boolean_t us_found; -} modify_db_state_t; - -typedef struct add_db_state { - laadm_grp_attr_db_t *as_attr; - boolean_t as_found; -} add_db_state_t; - -static int i_laadm_fput_grp(FILE *, laadm_grp_attr_db_t *); - -static int -i_laadm_strioctl(int fd, int cmd, void *ptr, int ilen) -{ - struct strioctl str; - - str.ic_cmd = cmd; - str.ic_timout = 0; - str.ic_len = ilen; - str.ic_dp = ptr; - - return (ioctl(fd, I_STR, &str)); -} - -/* - * Open and lock the aggregation configuration file lock. The lock is - * acquired as a reader (F_RDLCK) or writer (F_WRLCK). - */ -static int -i_laadm_lock_db(short type) -{ - int lock_fd; - struct flock lock; - - if ((lock_fd = open(LAADM_DB_LOCK, O_RDWR | O_CREAT | O_TRUNC, - LAADM_DB_PERMS)) < 0) - return (-1); - - lock.l_type = type; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - - if (fcntl(lock_fd, F_SETLKW, &lock) < 0) { - (void) close(lock_fd); - (void) unlink(LAADM_DB_LOCK); - return (-1); - } - return (lock_fd); -} - -/* - * Unlock and close the specified file. - */ -static void -i_laadm_unlock_db(int fd) -{ - struct flock lock; - - if (fd < 0) - return; - - lock.l_type = F_UNLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - - (void) fcntl(fd, F_SETLKW, &lock); - (void) close(fd); - (void) unlink(LAADM_DB_LOCK); -} - -/* - * Walk through the groups defined on the system and for each group , - * invoke (, ); - * Terminate the walk if at any time returns non-NULL value - */ -int -laadm_walk_sys(int (*fn)(void *, laadm_grp_attr_sys_t *), void *arg) -{ - laioc_info_t *ioc; - laioc_info_group_t *grp; - laioc_info_port_t *port; - laadm_grp_attr_sys_t attr; - int rc, i, j, bufsize, fd; - char *where; - - if ((fd = open(LAADM_DEV, O_RDWR)) == -1) - return (-1); - - bufsize = MIN_INFO_SIZE; - ioc = (laioc_info_t *)calloc(1, bufsize); - if (ioc == NULL) { - (void) close(fd); - errno = ENOMEM; - return (-1); - } - -tryagain: - rc = i_laadm_strioctl(fd, LAIOC_INFO, ioc, bufsize); - - if (rc != 0) { - if (errno == ENOSPC) { - /* - * The LAIOC_INFO call failed due to a short - * buffer. Reallocate the buffer and try again. - */ - bufsize *= 2; - if (bufsize <= MAX_INFO_SIZE) { - ioc = (laioc_info_t *)realloc(ioc, bufsize); - if (ioc != NULL) { - bzero(ioc, sizeof (bufsize)); - goto tryagain; - } - } - } - goto bail; - } - - /* - * Go through each group returned by the aggregation driver. - */ - where = (char *)(ioc + 1); - for (i = 0; i < ioc->li_ngroups; i++) { - /* LINTED E_BAD_PTR_CAST_ALIGN */ - grp = (laioc_info_group_t *)where; - - attr.lg_key = grp->lg_key; - attr.lg_nports = grp->lg_nports; - attr.lg_policy = grp->lg_policy; - attr.lg_lacp_mode = grp->lg_lacp_mode; - attr.lg_lacp_timer = grp->lg_lacp_timer; - - bcopy(grp->lg_mac, attr.lg_mac, ETHERADDRL); - attr.lg_mac_fixed = grp->lg_mac_fixed; - - attr.lg_ports = malloc(grp->lg_nports * - sizeof (laadm_port_attr_sys_t)); - if (attr.lg_ports == NULL) { - errno = ENOMEM; - goto bail; - } - - where = (char *)(grp + 1); - - /* - * Go through each port that is part of the group. - */ - for (j = 0; j < grp->lg_nports; j++) { - /* LINTED E_BAD_PTR_CAST_ALIGN */ - port = (laioc_info_port_t *)where; - - bcopy(port->lp_devname, attr.lg_ports[j].lp_devname, - MAXNAMELEN + 1); - bcopy(port->lp_mac, attr.lg_ports[j].lp_mac, - ETHERADDRL); - attr.lg_ports[j].lp_state = port->lp_state; - attr.lg_ports[j].lp_lacp_state = port->lp_lacp_state; - - where = (char *)(port + 1); - } - - rc = fn(arg, &attr); - free(attr.lg_ports); - if (rc != 0) - goto bail; - } - -bail: - free(ioc); - (void) close(fd); - return (rc); -} - -/* - * Parse one line of the link aggregation DB, and return the corresponding - * group. Memory for the ports associated with the aggregation may be - * allocated. It is the responsibility of the caller to free the lt_ports - * aggregation group attribute. - * - * Returns -1 on parsing failure, or 0 on success. - */ -static int -i_laadm_parse_db(char *line, laadm_grp_attr_db_t *attr) -{ - char *token; - int i; - int value; - char *endp = NULL; - char *lasts = NULL; - - bzero(attr, sizeof (*attr)); - - /* key */ - if ((token = strtok_r(line, " \t", &lasts)) == NULL) - goto failed; - - errno = 0; - value = (int)strtol(token, &endp, 10); - if (errno != 0 || *endp != '\0') - goto failed; - - attr->lt_key = value; - - /* policy */ - if ((token = strtok_r(NULL, " \t", &lasts)) == NULL || - !laadm_str_to_policy(token, &attr->lt_policy)) - goto failed; - - /* number of ports */ - if ((token = strtok_r(NULL, " \t", &lasts)) == NULL) - return (-1); - - errno = 0; - value = (int)strtol(token, &endp, 10); - if (errno != 0 || *endp != '\0') - goto failed; - - attr->lt_nports = value; - - /* ports */ - if ((attr->lt_ports = malloc(attr->lt_nports * - sizeof (laadm_port_attr_db_t))) == NULL) - goto failed; - - for (i = 0; i < attr->lt_nports; i++) { - char *where, *devname; - - /* port */ - if ((token = strtok_r(NULL, ", \t\n", &lasts)) == NULL) - goto failed; - - /* - * device name: In a previous version of this file, a port - * number could be specified using /. - * This syntax is unecessary and obsolete. - */ - if ((devname = strtok_r(token, "/", &where)) == NULL) - goto failed; - if (strlcpy(attr->lt_ports[i].lp_devname, devname, - MAXNAMELEN) >= MAXNAMELEN) - goto failed; - } - - /* unicast MAC address */ - if ((token = strtok_r(NULL, " \t\n", &lasts)) == NULL || - !laadm_str_to_mac_addr(token, &attr->lt_mac_fixed, - attr->lt_mac)) - goto failed; - - /* LACP mode */ - if ((token = strtok_r(NULL, " \t\n", &lasts)) == NULL || - !laadm_str_to_lacp_mode(token, &attr->lt_lacp_mode)) - attr->lt_lacp_mode = AGGR_LACP_OFF; - - /* LACP timer */ - if ((token = strtok_r(NULL, " \t\n", &lasts)) == NULL || - !laadm_str_to_lacp_timer(token, &attr->lt_lacp_timer)) - attr->lt_lacp_timer = AGGR_LACP_TIMER_SHORT; - - return (0); - -failed: - free(attr->lt_ports); - attr->lt_ports = NULL; - return (-1); -} - -/* - * Walk through the groups defined in the DB and for each group , - * invoke (, ); - */ -static int -i_laadm_walk_db(int (*fn)(void *, laadm_grp_attr_db_t *, laadm_diag_t *), - void *arg, const char *root, laadm_diag_t *diag) -{ - FILE *fp; - char line[MAXLINELEN]; - laadm_grp_attr_db_t attr; - char *db_file; - char db_file_buf[MAXPATHLEN]; - int lock_fd, retval = -1; - - if (root == NULL) { - db_file = LAADM_DB; - } else { - (void) snprintf(db_file_buf, MAXPATHLEN, "%s%s", root, - LAADM_DB); - db_file = db_file_buf; - } - - lock_fd = i_laadm_lock_db(F_RDLCK); - - if ((fp = fopen(db_file, "r")) == NULL) { - i_laadm_unlock_db(lock_fd); - *diag = LAADM_DIAG_REPOSITORY_OPENFAIL; - return (-1); - } - - bzero(&attr, sizeof (attr)); - - while (fgets(line, MAXLINELEN, fp) != NULL) { - /* skip comments */ - if (BLANK_LINE(line)) - continue; - - if (i_laadm_parse_db(line, &attr) != 0) { - errno = EFAULT; - *diag = LAADM_DIAG_REPOSITORY_PARSEFAIL; - goto failed; - } - - if (fn(arg, &attr, diag) != 0) - goto failed; - - free(attr.lt_ports); - attr.lt_ports = NULL; - } - retval = 0; - -failed: - free(attr.lt_ports); - (void) fclose(fp); - i_laadm_unlock_db(lock_fd); - return (retval); -} - -/* - * Send an add or remove command to the link aggregation driver. - */ -static int -i_laadm_add_rem_sys(laadm_grp_attr_db_t *attr, int cmd, laadm_diag_t *diag) -{ - int i, rc, fd, len; - laioc_add_rem_t *iocp; - laioc_port_t *ports; - - len = sizeof (*iocp) + attr->lt_nports * sizeof (laioc_port_t); - iocp = malloc(len); - if (iocp == NULL) - goto failed; - - iocp->la_key = attr->lt_key; - iocp->la_nports = attr->lt_nports; - ports = (laioc_port_t *)(iocp + 1); - - for (i = 0; i < attr->lt_nports; i++) { - if (strlcpy(ports[i].lp_devname, - attr->lt_ports[i].lp_devname, - MAXNAMELEN) >= MAXNAMELEN) - goto failed; - } - - if ((fd = open(LAADM_DEV, O_RDWR)) < 0) { - *diag = LAADM_DIAG_REPOSITORY_OPENFAIL; - goto failed; - } - - rc = i_laadm_strioctl(fd, cmd, iocp, len); - if ((rc < 0) && (errno == EINVAL)) - *diag = LAADM_DIAG_INVALID_INTFNAME; - - (void) close(fd); - - free(iocp); - return (rc); - -failed: - free(iocp); - return (-1); -} - -/* - * Send a modify command to the link aggregation driver. - */ -static int -i_laadm_modify_sys(uint32_t key, uint32_t mask, laadm_modify_attr_t *attr, - laadm_diag_t *diag) -{ - int rc, fd; - laioc_modify_t ioc; - - ioc.lu_key = key; - - ioc.lu_modify_mask = 0; - if (mask & LAADM_MODIFY_POLICY) - ioc.lu_modify_mask |= LAIOC_MODIFY_POLICY; - if (mask & LAADM_MODIFY_MAC) - ioc.lu_modify_mask |= LAIOC_MODIFY_MAC; - if (mask & LAADM_MODIFY_LACP_MODE) - ioc.lu_modify_mask |= LAIOC_MODIFY_LACP_MODE; - if (mask & LAADM_MODIFY_LACP_TIMER) - ioc.lu_modify_mask |= LAIOC_MODIFY_LACP_TIMER; - - ioc.lu_policy = attr->ld_policy; - ioc.lu_mac_fixed = attr->ld_mac_fixed; - bcopy(attr->ld_mac, ioc.lu_mac, ETHERADDRL); - ioc.lu_lacp_mode = attr->ld_lacp_mode; - ioc.lu_lacp_timer = attr->ld_lacp_timer; - - if ((fd = open(LAADM_DEV, O_RDWR)) < 0) { - *diag = LAADM_DIAG_REPOSITORY_OPENFAIL; - return (-1); - } - - rc = i_laadm_strioctl(fd, LAIOC_MODIFY, &ioc, sizeof (ioc)); - if ((rc < 0) && (errno == EINVAL)) - *diag = LAADM_DIAG_INVALID_MACADDR; - - (void) close(fd); - - return (rc); -} - -/* - * Send a create command to the link aggregation driver. - */ -static int -i_laadm_create_sys(int fd, laadm_grp_attr_db_t *attr, laadm_diag_t *diag) -{ - int i, rc, len; - laioc_create_t *iocp; - laioc_port_t *ports; - - len = sizeof (*iocp) + attr->lt_nports * sizeof (laioc_port_t); - iocp = malloc(len); - if (iocp == NULL) - return (-1); - - iocp->lc_key = attr->lt_key; - iocp->lc_nports = attr->lt_nports; - iocp->lc_policy = attr->lt_policy; - iocp->lc_lacp_mode = attr->lt_lacp_mode; - iocp->lc_lacp_timer = attr->lt_lacp_timer; - - ports = (laioc_port_t *)(iocp + 1); - - for (i = 0; i < attr->lt_nports; i++) { - if (strlcpy(ports[i].lp_devname, - attr->lt_ports[i].lp_devname, - MAXNAMELEN) >= MAXNAMELEN) { - errno = EINVAL; - free(iocp); - return (-1); - } - } - - if (attr->lt_mac_fixed && - ((bcmp(zero_mac, attr->lt_mac, ETHERADDRL) == 0) || - (attr->lt_mac[0] & 0x01))) { - errno = EINVAL; - *diag = LAADM_DIAG_INVALID_MACADDR; - free(iocp); - return (-1); - } - - bcopy(attr->lt_mac, iocp->lc_mac, ETHERADDRL); - iocp->lc_mac_fixed = attr->lt_mac_fixed; - - rc = i_laadm_strioctl(fd, LAIOC_CREATE, iocp, len); - if (rc < 0) - *diag = LAADM_DIAG_INVALID_INTFNAME; - - free(iocp); - return (rc); -} - -/* - * Invoked to bring up a link aggregation group. - */ -static int -i_laadm_up(void *arg, laadm_grp_attr_db_t *attr, laadm_diag_t *diag) -{ - laadm_up_t *up = (laadm_up_t *)arg; - - if (up->lu_key != 0 && up->lu_key != attr->lt_key) - return (0); - - up->lu_found = B_TRUE; - - if (i_laadm_create_sys(up->lu_fd, attr, diag) < 0 && - up->lu_key != 0) { - return (-1); - } - - return (0); -} - -/* - * Bring up a link aggregation group or all of them if the key is zero. - * If key is 0, walk may terminate early if any of the links fail - */ -int -laadm_up(uint32_t key, const char *root, laadm_diag_t *diag) -{ - laadm_up_t up; - - if ((up.lu_fd = open(LAADM_DEV, O_RDWR)) < 0) - return (-1); - - up.lu_key = key; - up.lu_found = B_FALSE; - - if (i_laadm_walk_db(i_laadm_up, &up, root, diag) < 0) { - (void) close(up.lu_fd); - return (-1); - } - (void) close(up.lu_fd); - - /* - * only return error if user specified key and key was - * not found - */ - if (!up.lu_found && key != 0) { - errno = ENOENT; - return (-1); - } - - return (0); -} -/* - * Send a delete command to the link aggregation driver. - */ -static int -i_laadm_delete_sys(int fd, laadm_grp_attr_sys_t *attr) -{ - laioc_delete_t ioc; - - ioc.ld_key = attr->lg_key; - - return (i_laadm_strioctl(fd, LAIOC_DELETE, &ioc, sizeof (ioc))); -} - -/* - * Invoked to bring down a link aggregation group. - */ -static int -i_laadm_down(void *arg, laadm_grp_attr_sys_t *attr) -{ - laadm_down_t *down = (laadm_down_t *)arg; - int fd; - - if (down->ld_key != 0 && down->ld_key != attr->lg_key) - return (0); - - down->ld_found = B_TRUE; - - if ((fd = open(LAADM_DEV, O_RDWR)) < 0) - return (-1); - - if (i_laadm_delete_sys(fd, attr) < 0 && down->ld_key != 0) { - (void) close(fd); - return (-1); - } - - (void) close(fd); - return (0); -} - -/* - * Bring down a link aggregation group or all of them if the key is zero. - * If key is 0, walk may terminate early if any of the links fail - */ -int -laadm_down(uint32_t key) -{ - laadm_down_t down; - - down.ld_key = key; - down.ld_found = B_FALSE; - - if (laadm_walk_sys(i_laadm_down, &down) < 0) - return (-1); - - /* - * only return error if user specified key and key was - * not found - */ - if (!down.ld_found && key != 0) { - errno = ENOENT; - return (-1); - } - - return (0); -} - -/* - * For each group found in the DB, invokes (, ). - * - * The following values can be returned by (): - * - * -1: an error occured. This will cause the walk to be terminated, - * and the original DB file to be preserved. - * - * 0: success and write. The walker will write the contents of - * the attribute passed as argument to (), and continue walking - * the entries found in the DB. - * - * 1: skip. The walker should not write the contents of the current - * group attributes to the new DB, but should continue walking - * the entries found in the DB. - */ -static int -i_laadm_walk_rw_db(int (*fn)(void *, laadm_grp_attr_db_t *), - void *arg, - const char *root, - laadm_diag_t *diag) -{ - FILE *fp, *nfp; - int nfd, fn_rc, lock_fd; - char line[MAXLINELEN]; - laadm_grp_attr_db_t attr; - char *db_file, *tmp_db_file; - char db_file_buf[MAXPATHLEN]; - char tmp_db_file_buf[MAXPATHLEN]; - - if (root == NULL) { - db_file = LAADM_DB; - tmp_db_file = LAADM_DB_TMP; - } else { - (void) snprintf(db_file_buf, MAXPATHLEN, "%s%s", root, - LAADM_DB); - (void) snprintf(tmp_db_file_buf, MAXPATHLEN, "%s%s", root, - LAADM_DB_TMP); - db_file = db_file_buf; - tmp_db_file = tmp_db_file_buf; - } - - if ((lock_fd = i_laadm_lock_db(F_WRLCK)) < 0) - return (-1); - - if ((fp = fopen(db_file, "r")) == NULL) { - i_laadm_unlock_db(lock_fd); - *diag = LAADM_DIAG_REPOSITORY_OPENFAIL; - return (-1); - } - - if ((nfd = open(tmp_db_file, O_WRONLY|O_CREAT|O_TRUNC, - LAADM_DB_PERMS)) == -1) { - (void) fclose(fp); - i_laadm_unlock_db(lock_fd); - return (-1); - } - - if ((nfp = fdopen(nfd, "w")) == NULL) { - (void) close(nfd); - (void) fclose(fp); - (void) unlink(tmp_db_file); - i_laadm_unlock_db(lock_fd); - *diag = LAADM_DIAG_REPOSITORY_OPENFAIL; - return (-1); - } - - attr.lt_ports = NULL; - - while (fgets(line, MAXLINELEN, fp) != NULL) { - - /* skip comments */ - if (BLANK_LINE(line)) { - if (fputs(line, nfp) == EOF) - goto failed; - continue; - } - - if (i_laadm_parse_db(line, &attr) != 0) { - errno = EFAULT; - *diag = LAADM_DIAG_REPOSITORY_PARSEFAIL; - goto failed; - } - - fn_rc = fn(arg, &attr); - - switch (fn_rc) { - case -1: - /* failure, stop walking */ - goto failed; - case 0: - /* - * Success, write group attributes, which could - * have been modified by fn(). - */ - if (i_laadm_fput_grp(nfp, &attr) != 0) - goto failed; - break; - case 1: - /* skip current group */ - break; - } - - free(attr.lt_ports); - attr.lt_ports = NULL; - } - - if (getuid() == 0 || geteuid() == 0) { - if (fchmod(nfd, LAADM_DB_PERMS) == -1) - goto failed; - - if (fchown(nfd, LAADM_DB_OWNER, LAADM_DB_GROUP) == -1) - goto failed; - } - - if (fflush(nfp) == EOF) - goto failed; - - (void) fclose(fp); - (void) fclose(nfp); - - if (rename(tmp_db_file, db_file) == -1) { - (void) unlink(tmp_db_file); - i_laadm_unlock_db(lock_fd); - return (-1); - } - - i_laadm_unlock_db(lock_fd); - return (0); - -failed: - free(attr.lt_ports); - (void) fclose(fp); - (void) fclose(nfp); - (void) unlink(tmp_db_file); - i_laadm_unlock_db(lock_fd); - - return (-1); -} - -/* - * Remove an entry from the DB. - */ -static int -i_laadm_delete_db_fn(void *arg, laadm_grp_attr_db_t *grp) -{ - delete_db_state_t *state = arg; - - if (grp->lt_key != state->ds_key) - return (0); - - state->ds_found = B_TRUE; - - /* don't save matching group */ - return (1); -} - -static int -i_laadm_delete_db(laadm_grp_attr_db_t *attr, const char *root, - laadm_diag_t *diag) -{ - delete_db_state_t state; - - state.ds_key = attr->lt_key; - state.ds_found = B_FALSE; - - if (i_laadm_walk_rw_db(i_laadm_delete_db_fn, &state, root, - diag) != 0) - return (-1); - - if (!state.ds_found) { - errno = ENOENT; - return (-1); - } - - return (0); -} - -/* - * Modify the properties of an existing group in the DB. - */ -static int -i_laadm_modify_db_fn(void *arg, laadm_grp_attr_db_t *grp) -{ - modify_db_state_t *state = arg; - laadm_modify_attr_t *new_attr = state->us_attr_new; - laadm_modify_attr_t *old_attr = state->us_attr_old; - - if (grp->lt_key != state->us_key) - return (0); - - state->us_found = B_TRUE; - - if (state->us_mask & LAADM_MODIFY_POLICY) { - if (old_attr != NULL) - old_attr->ld_policy = grp->lt_policy; - grp->lt_policy = new_attr->ld_policy; - } - - if (state->us_mask & LAADM_MODIFY_MAC) { - if (old_attr != NULL) { - old_attr->ld_mac_fixed = grp->lt_mac_fixed; - bcopy(grp->lt_mac, old_attr->ld_mac, ETHERADDRL); - } - grp->lt_mac_fixed = new_attr->ld_mac_fixed; - bcopy(new_attr->ld_mac, grp->lt_mac, ETHERADDRL); - } - - if (state->us_mask & LAADM_MODIFY_LACP_MODE) { - if (old_attr != NULL) - old_attr->ld_lacp_mode = grp->lt_lacp_mode; - grp->lt_lacp_mode = new_attr->ld_lacp_mode; - } - - if (state->us_mask & LAADM_MODIFY_LACP_TIMER) { - if (old_attr != NULL) - old_attr->ld_lacp_timer = grp->lt_lacp_timer; - grp->lt_lacp_timer = new_attr->ld_lacp_timer; - } - - /* save modified group */ - return (0); -} - -static int -i_laadm_modify_db(uint32_t key, uint32_t mask, laadm_modify_attr_t *new, - laadm_modify_attr_t *old, const char *root, laadm_diag_t *diag) -{ - modify_db_state_t state; - - state.us_key = key; - state.us_mask = mask; - state.us_attr_new = new; - state.us_attr_old = old; - state.us_found = B_FALSE; - - if (i_laadm_walk_rw_db(i_laadm_modify_db_fn, &state, root, - diag) != 0) - return (-1); - - if (!state.us_found) { - errno = ENOENT; - return (-1); - } - - return (0); -} - -/* - * Add ports to an existing group in the DB. - */ -static int -i_laadm_add_db_fn(void *arg, laadm_grp_attr_db_t *grp) -{ - add_db_state_t *state = arg; - laadm_grp_attr_db_t *attr = state->as_attr; - void *ports; - int i, j; - - if (grp->lt_key != attr->lt_key) - return (0); - - state->as_found = B_TRUE; - - /* are any of the ports to be added already members of the group? */ - for (i = 0; i < grp->lt_nports; i++) { - for (j = 0; j < attr->lt_nports; j++) { - if (strcmp(grp->lt_ports[i].lp_devname, - attr->lt_ports[j].lp_devname) == 0) { - errno = EEXIST; - return (-1); - } - } - } - - /* add groups specified by attr to grp */ - ports = realloc(grp->lt_ports, (grp->lt_nports + - attr->lt_nports) * sizeof (laadm_port_attr_db_t)); - if (ports == NULL) - return (-1); - grp->lt_ports = ports; - - for (i = 0; i < attr->lt_nports; i++) { - if (strlcpy(grp->lt_ports[grp->lt_nports + i].lp_devname, - attr->lt_ports[i].lp_devname, MAXNAMELEN + 1) >= - MAXNAMELEN + 1) - return (-1); - } - - grp->lt_nports += attr->lt_nports; - - /* save modified group */ - return (0); -} - -static int -i_laadm_add_db(laadm_grp_attr_db_t *attr, const char *root, - laadm_diag_t *diag) -{ - add_db_state_t state; - - state.as_attr = attr; - state.as_found = B_FALSE; - - if (i_laadm_walk_rw_db(i_laadm_add_db_fn, &state, root, - diag) != 0) - return (-1); - - if (!state.as_found) { - errno = ENOENT; - return (-1); - } - - return (0); -} - -/* - * Remove ports from an existing group in the DB. - */ - -typedef struct remove_db_state { - laadm_grp_attr_db_t *rs_attr; - boolean_t rs_found; -} remove_db_state_t; - -static int -i_laadm_remove_db_fn(void *arg, laadm_grp_attr_db_t *grp) -{ - remove_db_state_t *state = (remove_db_state_t *)arg; - laadm_grp_attr_db_t *attr = state->rs_attr; - int i, j, k, nremoved; - boolean_t match; - - if (grp->lt_key != attr->lt_key) - return (0); - - state->rs_found = B_TRUE; - - /* remove the ports specified by attr from the group */ - nremoved = 0; - k = 0; - for (i = 0; i < grp->lt_nports; i++) { - match = B_FALSE; - for (j = 0; j < attr->lt_nports && !match; j++) { - match = (strcmp(grp->lt_ports[i].lp_devname, - attr->lt_ports[j].lp_devname) == 0); - } - if (match) - nremoved++; - else - grp->lt_ports[k++] = grp->lt_ports[i]; - } - - if (nremoved != attr->lt_nports) { - errno = ENOENT; - return (-1); - } - - grp->lt_nports -= nremoved; - - /* save modified group */ - return (0); -} - -static int -i_laadm_remove_db(laadm_grp_attr_db_t *attr, const char *root, - laadm_diag_t *diag) -{ - remove_db_state_t state; - - state.rs_attr = attr; - state.rs_found = B_FALSE; - - if (i_laadm_walk_rw_db(i_laadm_remove_db_fn, &state, root, - diag) != 0) - return (-1); - - if (!state.rs_found) { - errno = ENOENT; - return (-1); - } - - return (0); -} - -/* - * Given a policy string, return a policy mask. Returns B_TRUE on - * success, or B_FALSE if an error occured during parsing. - */ -boolean_t -laadm_str_to_policy(const char *str, uint32_t *policy) -{ - int i; - policy_t *pol; - char *token = NULL; - char *lasts; - - *policy = 0; - - while ((token = strtok_r((token == NULL) ? (char *)str : NULL, ",", - &lasts)) != NULL) { - for (i = 0; i < NPOLICIES; i++) { - pol = &policies[i]; - if (strcasecmp(token, pol->pol_name) == 0) { - *policy |= pol->policy; - break; - } - } - if (i == NPOLICIES) - return (B_FALSE); - } - - return (B_TRUE); -} - -/* - * Given a policy mask, returns a printable string, or NULL if the - * policy mask is invalid. It is the responsibility of the caller to - * free the returned string after use. - */ -char * -laadm_policy_to_str(uint32_t policy, char *str) -{ - int i, npolicies = 0; - policy_t *pol; - - str[0] = '\0'; - - for (i = 0; i < NPOLICIES; i++) { - pol = &policies[i]; - if ((policy & pol->policy) != 0) { - npolicies++; - if (npolicies > 1) - (void) strcat(str, ","); - (void) strcat(str, pol->pol_name); - } - } - - return (str); -} - -/* - * Given a MAC address string, return the MAC address in the mac_addr - * array. If the MAC address was not explicitly specified, i.e. is - * equal to 'auto', zero out mac-addr and set mac_fixed to B_TRUE. - * Return B_FALSE if a syntax error was encountered, B_FALSE otherwise. - */ -boolean_t -laadm_str_to_mac_addr(const char *str, boolean_t *mac_fixed, uchar_t *mac_addr) -{ - uchar_t *conv_str; - int mac_len; - - *mac_fixed = (strcmp(str, "auto") != 0); - if (!*mac_fixed) { - bzero(mac_addr, ETHERADDRL); - return (B_TRUE); - } - - conv_str = _link_aton(str, &mac_len); - if (conv_str == NULL) - return (B_FALSE); - - if (mac_len != ETHERADDRL) { - free(conv_str); - return (B_FALSE); - } - - if ((bcmp(zero_mac, conv_str, ETHERADDRL) == 0) || - (conv_str[0] & 0x01)) { - free(conv_str); - return (B_FALSE); - } - - bcopy(conv_str, mac_addr, ETHERADDRL); - free(conv_str); - - return (B_TRUE); -} - -/* - * Returns a string containing a printable representation of a MAC address. - */ -const char * -laadm_mac_addr_to_str(unsigned char *mac, char *buf) -{ - static char unknown_mac[] = {0, 0, 0, 0, 0, 0}; - - if (buf == NULL) - return (NULL); - - if (bcmp(unknown_mac, mac, ETHERADDRL) == 0) - return (gettext("")); - else - return (_link_ntoa(mac, buf, ETHERADDRL, IFT_OTHER)); -} - -/* - * Given a LACP mode string, find the corresponding LACP mode number. Returns - * B_TRUE if a match was found, B_FALSE otherwise. - */ -boolean_t -laadm_str_to_lacp_mode(const char *str, aggr_lacp_mode_t *lacp_mode) -{ - int i; - laadm_lacp_mode_t *mode; - - for (i = 0; i < NLACP_MODES; i++) { - mode = &lacp_modes[i]; - if (strncasecmp(str, mode->mode_str, - strlen(mode->mode_str)) == 0) { - *lacp_mode = mode->mode_id; - return (B_TRUE); - } - } - - return (B_FALSE); -} - -/* - * Given a LACP mode number, returns a printable string, or NULL if the - * LACP mode number is invalid. - */ -const char * -laadm_lacp_mode_to_str(aggr_lacp_mode_t mode_id) -{ - int i; - laadm_lacp_mode_t *mode; - - for (i = 0; i < NLACP_MODES; i++) { - mode = &lacp_modes[i]; - if (mode->mode_id == mode_id) - return (mode->mode_str); - } - - return (NULL); -} - -/* - * Given a LACP timer string, find the corresponding LACP timer number. Returns - * B_TRUE if a match was found, B_FALSE otherwise. - */ -boolean_t -laadm_str_to_lacp_timer(const char *str, aggr_lacp_timer_t *lacp_timer) -{ - int i; - laadm_lacp_timer_t *timer; - - for (i = 0; i < NLACP_TIMERS; i++) { - timer = &lacp_timers[i]; - if (strncasecmp(str, timer->lt_str, - strlen(timer->lt_str)) == 0) { - *lacp_timer = timer->lt_id; - return (B_TRUE); - } - } - - return (B_FALSE); -} - -/* - * Given a LACP timer, returns a printable string, or NULL if the - * LACP timer number is invalid. - */ -const char * -laadm_lacp_timer_to_str(aggr_lacp_timer_t timer_id) -{ - int i; - laadm_lacp_timer_t *timer; - - for (i = 0; i < NLACP_TIMERS; i++) { - timer = &lacp_timers[i]; - if (timer->lt_id == timer_id) - return (timer->lt_str); - } - - return (NULL); -} - -#define FPRINTF_ERR(fcall) if ((fcall) < 0) return (-1); - -/* - * Write the attribute of a group to the specified file. Returns 0 on - * success, -1 on failure. - */ -static int -i_laadm_fput_grp(FILE *fp, laadm_grp_attr_db_t *attr) -{ - int i; - char addr_str[ETHERADDRL * 3]; - char policy_str[LAADM_POLICY_STR_LEN]; - - /* key, policy */ - FPRINTF_ERR(fprintf(fp, "%d\t%s\t", attr->lt_key, - laadm_policy_to_str(attr->lt_policy, policy_str))); - - /* number of ports, ports */ - FPRINTF_ERR(fprintf(fp, "%d\t", attr->lt_nports)); - for (i = 0; i < attr->lt_nports; i++) { - if (i > 0) - FPRINTF_ERR(fprintf(fp, ",")); - FPRINTF_ERR(fprintf(fp, "%s", attr->lt_ports[i].lp_devname)); - } - FPRINTF_ERR(fprintf(fp, "\t")); - - /* MAC address */ - if (!attr->lt_mac_fixed) { - FPRINTF_ERR(fprintf(fp, "auto")); - } else { - FPRINTF_ERR(fprintf(fp, "%s", - laadm_mac_addr_to_str(attr->lt_mac, addr_str))); - } - FPRINTF_ERR(fprintf(fp, "\t")); - - FPRINTF_ERR(fprintf(fp, "%s\t", - laadm_lacp_mode_to_str(attr->lt_lacp_mode))); - - FPRINTF_ERR(fprintf(fp, "%s\n", - laadm_lacp_timer_to_str(attr->lt_lacp_timer))); - - return (0); -} - -static int -i_laadm_create_db(laadm_grp_attr_db_t *attr, const char *root, - laadm_diag_t *diag) -{ - FILE *fp; - char line[MAXLINELEN]; - uint32_t key; - int lock_fd, retval = -1; - char *db_file; - char db_file_buf[MAXPATHLEN]; - char *endp = NULL; - - if (root == NULL) { - db_file = LAADM_DB; - } else { - (void) snprintf(db_file_buf, MAXPATHLEN, "%s%s", root, - LAADM_DB); - db_file = db_file_buf; - } - - if ((lock_fd = i_laadm_lock_db(F_WRLCK)) < 0) - return (-1); - - if ((fp = fopen(db_file, "r+")) == NULL && - (fp = fopen(db_file, "w")) == NULL) { - i_laadm_unlock_db(lock_fd); - *diag = LAADM_DIAG_REPOSITORY_OPENFAIL; - return (-1); - } - - /* look for existing group with same key */ - while (fgets(line, MAXLINELEN, fp) != NULL) { - char *holder, *lasts; - - /* skip comments */ - if (BLANK_LINE(line)) - continue; - - /* ignore corrupted lines */ - holder = strtok_r(line, " \t", &lasts); - if (holder == NULL) - continue; - - /* port number */ - errno = 0; - key = (int)strtol(holder, &endp, 10); - if (errno != 0 || *endp != '\0') { - goto failed; - } - - if (key == attr->lt_key) { - /* group with key already exists */ - errno = EEXIST; - goto failed; - } - } - - /* - * If we get here, we've verified that no existing group with - * the same key already exists. It's now time to add the - * new group to the DB. - */ - if (i_laadm_fput_grp(fp, attr) != 0) - goto failed; - - retval = 0; - -failed: - (void) fclose(fp); - i_laadm_unlock_db(lock_fd); - return (retval); -} - -/* - * Create a new link aggregation group. Update the configuration - * file and bring it up. - */ -int -laadm_create(uint32_t key, uint32_t nports, laadm_port_attr_db_t *ports, - uint32_t policy, boolean_t mac_addr_fixed, uchar_t *mac_addr, - aggr_lacp_mode_t lacp_mode, aggr_lacp_timer_t lacp_timer, boolean_t tempop, - const char *root, laadm_diag_t *diag) -{ - laadm_grp_attr_db_t attr; - int errno_sav; - - if (key == 0 || key > LAADM_MAX_KEY) { - errno = EINVAL; - *diag = LAADM_DIAG_INVALID_KEY; - return (-1); - } - - attr.lt_key = key; - attr.lt_nports = nports; - attr.lt_ports = ports; - attr.lt_policy = policy; - attr.lt_mac_fixed = mac_addr_fixed; - if (attr.lt_mac_fixed) - bcopy(mac_addr, attr.lt_mac, ETHERADDRL); - else - bzero(attr.lt_mac, ETHERADDRL); - attr.lt_lacp_mode = lacp_mode; - attr.lt_lacp_timer = lacp_timer; - - /* add the link aggregation group to the DB */ - if (!tempop) { - if (i_laadm_create_db(&attr, root, diag) < 0) - return (-1); - } else { - laadm_up_t up; - int rc; - - up.lu_key = key; - up.lu_found = B_FALSE; - up.lu_fd = open(LAADM_DEV, O_RDWR); - if (up.lu_fd < 0) - return (-1); - - rc = i_laadm_up((void *)&up, &attr, diag); - (void) close(up.lu_fd); - return (rc); - } - - /* bring up the link aggregation group */ - if (laadm_up(key, root, diag) < 0) { - if (errno != EEXIST) { - errno_sav = errno; - if (!tempop) { - (void) i_laadm_delete_db(&attr, root, - diag); - } - errno = errno_sav; - } - return (-1); - } - - return (0); -} - -/* - * Modify the parameters of an existing link aggregation group. Update - * the configuration file and pass the changes to the kernel. - */ -int -laadm_modify(uint32_t key, uint32_t modify_mask, uint32_t policy, - boolean_t mac_fixed, uchar_t *mac_addr, aggr_lacp_mode_t lacp_mode, - aggr_lacp_timer_t lacp_timer, boolean_t tempop, const char *root, - laadm_diag_t *diag) -{ - laadm_modify_attr_t new_attr, old_attr; - int errno_save; - - if (key == 0) { - errno = EINVAL; - *diag = LAADM_DIAG_INVALID_KEY; - return (-1); - } - - if (modify_mask & LAADM_MODIFY_POLICY) - new_attr.ld_policy = policy; - - if (modify_mask & LAADM_MODIFY_MAC) { - new_attr.ld_mac_fixed = mac_fixed; - bcopy(mac_addr, new_attr.ld_mac, ETHERADDRL); - } - - if (modify_mask & LAADM_MODIFY_LACP_MODE) - new_attr.ld_lacp_mode = lacp_mode; - - if (modify_mask & LAADM_MODIFY_LACP_TIMER) - new_attr.ld_lacp_timer = lacp_timer; - - /* update the DB */ - if (!tempop) { - if (i_laadm_modify_db(key, modify_mask, &new_attr, - &old_attr, root, diag) < 0) - return (-1); - } - - if (i_laadm_modify_sys(key, modify_mask, &new_attr, - diag) < 0) { - if (!tempop) { - errno_save = errno; - (void) i_laadm_modify_db(key, modify_mask, - &old_attr, NULL, root, diag); - errno = errno_save; - } - return (-1); - } - - return (0); -} - -/* - * Delete a previously created link aggregation group. - */ -int -laadm_delete(uint32_t key, boolean_t tempop, const char *root, - laadm_diag_t *diag) -{ - laadm_grp_attr_db_t db_attr; - - if (key == 0) { - errno = EINVAL; - *diag = LAADM_DIAG_INVALID_KEY; - return (-1); - } - - if (tempop) { - laadm_down_t down; - laadm_grp_attr_sys_t sys_attr; - - down.ld_key = key; - down.ld_found = B_FALSE; - sys_attr.lg_key = key; - return (i_laadm_down((void *)&down, &sys_attr)); - } else if ((laadm_down(key) < 0) && errno == EBUSY) { - return (-1); - } - - db_attr.lt_key = key; - - if (tempop) - return (0); - - return (i_laadm_delete_db(&db_attr, root, diag)); -} - -/* - * Add one or more ports to an existing link aggregation. - */ -int -laadm_add(uint32_t key, uint32_t nports, laadm_port_attr_db_t *ports, - boolean_t tempop, const char *root, laadm_diag_t *diag) -{ - laadm_grp_attr_db_t attr; - int errno_save; - - if (key == 0) { - errno = EINVAL; - *diag = LAADM_DIAG_INVALID_KEY; - return (-1); - } - - bzero(&attr, sizeof (attr)); - attr.lt_key = key; - attr.lt_nports = nports; - attr.lt_ports = ports; - - if (!tempop) { - if (i_laadm_add_db(&attr, root, diag) < 0) - return (-1); - } - - if (i_laadm_add_rem_sys(&attr, LAIOC_ADD, diag) < 0) { - if (!tempop) { - errno_save = errno; - (void) i_laadm_remove_db(&attr, root, diag); - errno = errno_save; - } - return (-1); - } - - return (0); -} - -/* - * Remove one or more ports from an existing link aggregation. - */ -int -laadm_remove(uint32_t key, uint32_t nports, laadm_port_attr_db_t *ports, - boolean_t tempop, const char *root, laadm_diag_t *diag) -{ - laadm_grp_attr_db_t attr; - int errno_save; - - if (key == 0) { - errno = EINVAL; - *diag = LAADM_DIAG_INVALID_KEY; - return (-1); - } - - bzero(&attr, sizeof (attr)); - attr.lt_key = key; - attr.lt_nports = nports; - attr.lt_ports = ports; - - if (!tempop) { - if (i_laadm_remove_db(&attr, root, diag) < 0) - return (-1); - } - - if (i_laadm_add_rem_sys(&attr, LAIOC_REMOVE, diag) < 0) { - if (!tempop) { - errno_save = errno; - (void) i_laadm_add_db(&attr, root, diag); - errno = errno_save; - } - return (-1); - } - - return (0); -} - -const char * -laadm_diag(laadm_diag_t diag) { - switch (diag) { - case LAADM_DIAG_REPOSITORY_OPENFAIL: - return (gettext("configuration repository open failed")); - case LAADM_DIAG_REPOSITORY_PARSEFAIL: - return (gettext("parsing of configuration repository failed")); - case LAADM_DIAG_REPOSITORY_CLOSEFAIL: - return (gettext("configuration repository close failed")); - case LAADM_DIAG_INVALID_INTFNAME: - return (gettext("invalid interface name")); - case LAADM_DIAG_INVALID_MACADDR: - return (gettext("invalid MAC address")); - case LAADM_DIAG_INVALID_KEY: - return (gettext("invalid key")); - default: - return (gettext("unknown diagnostic")); - } -} diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/liblaadm/common/liblaadm.h --- a/usr/src/lib/liblaadm/common/liblaadm.h Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _LIBLAADM_H -#define _LIBLAADM_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Modification flags sent with the LAIOC_MODIFY ioctl - */ -#define LAADM_MODIFY_POLICY 0x01 -#define LAADM_MODIFY_MAC 0x02 -#define LAADM_MODIFY_LACP_MODE 0x04 -#define LAADM_MODIFY_LACP_TIMER 0x08 - -#define LAADM_POLICY_STR_LEN 8 - -typedef struct laadm_port_attr_db { - char lp_devname[MAXNAMELEN + 1]; -} laadm_port_attr_db_t; - -typedef struct laadm_port_attr_sys { - char lp_devname[MAXNAMELEN + 1]; - uchar_t lp_mac[ETHERADDRL]; - aggr_port_state_t lp_state; - aggr_lacp_state_t lp_lacp_state; -} laadm_port_attr_sys_t; - -typedef struct laadm_grp_attr_sys { - uint32_t lg_key; - uint32_t lg_nports; - laadm_port_attr_sys_t *lg_ports; - uint32_t lg_policy; - uchar_t lg_mac[ETHERADDRL]; - boolean_t lg_mac_fixed; - aggr_lacp_mode_t lg_lacp_mode; - aggr_lacp_timer_t lg_lacp_timer; -} laadm_grp_attr_sys_t; - -/* - * Diagnostic codes. These supplement error messages. - */ -typedef enum { - LAADM_DIAG_REPOSITORY_OPENFAIL = 1, - LAADM_DIAG_REPOSITORY_PARSEFAIL = 2, - LAADM_DIAG_REPOSITORY_CLOSEFAIL = 3, - LAADM_DIAG_INVALID_INTFNAME = 4, - LAADM_DIAG_INVALID_MACADDR = 5, - LAADM_DIAG_INVALID_KEY = 6 -} laadm_diag_t; - -extern int laadm_create(uint32_t, uint32_t, laadm_port_attr_db_t *, - uint32_t, boolean_t, uchar_t *, aggr_lacp_mode_t, aggr_lacp_timer_t, - boolean_t, const char *, laadm_diag_t *); -extern int laadm_delete(uint32_t, boolean_t, const char *, - laadm_diag_t *); -extern int laadm_add(uint32_t, uint32_t, laadm_port_attr_db_t *, - boolean_t, const char *, laadm_diag_t *); -extern int laadm_remove(uint32_t, uint32_t, laadm_port_attr_db_t *, - boolean_t, const char *, laadm_diag_t *); -extern int laadm_modify(uint32_t, uint32_t, uint32_t, boolean_t, - uchar_t *, aggr_lacp_mode_t, aggr_lacp_timer_t, boolean_t, const char *, - laadm_diag_t *); -extern int laadm_up(uint32_t, const char *, laadm_diag_t *); -extern int laadm_down(uint32_t); - -extern boolean_t laadm_str_to_policy(const char *, uint32_t *); -extern char *laadm_policy_to_str(uint32_t, char *buf); -extern boolean_t laadm_str_to_mac_addr(const char *, boolean_t *, uchar_t *); -extern const char *laadm_mac_addr_to_str(unsigned char *, char *); - -extern boolean_t laadm_str_to_lacp_mode(const char *, aggr_lacp_mode_t *); -extern const char *laadm_lacp_mode_to_str(aggr_lacp_mode_t); -extern boolean_t laadm_str_to_lacp_timer(const char *, aggr_lacp_timer_t *); -extern const char *laadm_lacp_timer_to_str(aggr_lacp_timer_t); - -extern int laadm_walk_sys(int (*)(void *, laadm_grp_attr_sys_t *), void *); -extern const char *laadm_diag(laadm_diag_t); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBLAADM_H */ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/liblaadm/common/llib-llaadm --- a/usr/src/lib/liblaadm/common/llib-llaadm Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ -/*PROTOLIB1*/ - -#include diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/liblaadm/common/mapfile-vers --- a/usr/src/lib/liblaadm/common/mapfile-vers Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -SUNWprivate_1.1 { - global: - laadm_add; - laadm_create; - laadm_delete; - laadm_diag; - laadm_down; - laadm_lacp_mode_to_str; - laadm_lacp_timer_to_str; - laadm_mac_addr_to_str; - laadm_modify; - laadm_policy_to_str; - laadm_remove; - laadm_str_to_lacp_mode; - laadm_str_to_lacp_timer; - laadm_str_to_mac_addr; - laadm_str_to_policy; - laadm_up; - laadm_walk_sys; - local: - *; -}; diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/liblaadm/i386/Makefile --- a/usr/src/lib/liblaadm/i386/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#pragma ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/liblaadm/sparc/Makefile --- a/usr/src/lib/liblaadm/sparc/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#pragma ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libmacadm/Makefile --- a/usr/src/lib/libmacadm/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include $(SRC)/lib/Makefile.lib - -HDRS = libmacadm.h -HDRDIR = common - -SUBDIRS = $(MACH) - -POFILE = libmacadm.po -MSGFILES = common/libmacadm.c - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint - -.KEEP_STATE: - -all clean clobber install lint: $(SUBDIRS) - -install_h: $(ROOTHDRS) - -check: $(CHECKHDRS) - -$(POFILE): pofile_MSGFILES - -_msg: $(MSGDOMAINPOFILE) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include $(SRC)/Makefile.msg.targ -include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libmacadm/Makefile.com --- a/usr/src/lib/libmacadm/Makefile.com Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -LIBRARY = libmacadm.a -VERS = .1 -OBJECTS = libmacadm.o - -include ../../Makefile.lib - -# install this library in the root filesystem -include ../../Makefile.rootfs - -LIBS = $(DYNLIB) $(LINTLIB) - -LDLIBS += -ldevinfo -lc - -SRCDIR = ../common -$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) -D_REENTRANT - -.KEEP_STATE: - -all: $(LIBS) fnamecheck - -lint: lintcheck - -include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libmacadm/common/libmacadm.c --- a/usr/src/lib/libmacadm/common/libmacadm.c Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define _KERNEL -#include -#undef _KERNEL - -/* - * MAC Administration Library. - * - * This library is used by administration tools such as dladm(1M) to - * iterate through the list of MAC interfaces - * - */ - -typedef struct macadm_dev { - char md_name[MAXNAMELEN]; - struct macadm_dev *md_next; -} macadm_dev_t; - -typedef struct macadm_walk { - macadm_dev_t *mw_dev_list; -} macadm_walk_t; - -/* - * Local callback invoked for each DDI_NT_NET node. - */ -/* ARGSUSED */ -static int -i_macadm_apply(di_node_t node, di_minor_t minor, void *arg) -{ - macadm_walk_t *mwp = arg; - macadm_dev_t *mdp = mwp->mw_dev_list; - macadm_dev_t **lastp = &mwp->mw_dev_list; - char dev[MAXNAMELEN]; - - (void) snprintf(dev, MAXNAMELEN, "%s%d", - di_driver_name(node), di_instance(node)); - - /* - * Skip aggregations. - */ - if (strcmp("aggr", di_driver_name(node)) == 0) - return (DI_WALK_CONTINUE); - - while (mdp) { - /* - * Skip duplicates. - */ - if (strcmp(mdp->md_name, dev) == 0) - return (DI_WALK_CONTINUE); - - lastp = &mdp->md_next; - mdp = mdp->md_next; - } - - if ((mdp = malloc(sizeof (*mdp))) == NULL) - return (DI_WALK_CONTINUE); - - (void) strlcpy(mdp->md_name, dev, MAXNAMELEN); - mdp->md_next = NULL; - *lastp = mdp; - - return (DI_WALK_CONTINUE); -} - -/* - * Invoke the specified callback for each DDI_NT_MAC node. - */ -int -macadm_walk(void (*fn)(void *, const char *), void *arg, - boolean_t use_cache) -{ - di_node_t root; - macadm_walk_t mw; - macadm_dev_t *mdp; - uint_t flags; - - if (use_cache) { - flags = DINFOCACHE; - } else { - flags = DINFOSUBTREE | DINFOMINOR | DINFOPROP | DINFOFORCE; - } - - if ((root = di_init("/", flags)) == DI_NODE_NIL) { - return (-1); - } - mw.mw_dev_list = NULL; - - (void) di_walk_minor(root, DDI_NT_NET, DI_CHECK_ALIAS, &mw, - i_macadm_apply); - - di_fini(root); - - mdp = mw.mw_dev_list; - while (mdp) { - (*fn)(arg, mdp->md_name); - mdp = mdp->md_next; - } - - return (0); -} diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libmacadm/common/libmacadm.h --- a/usr/src/lib/libmacadm/common/libmacadm.h Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _LIBMACADM_H -#define _LIBMACADM_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern int macadm_walk(void (*)(void *, const char *), - void *, boolean_t); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBMACADM_H */ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libmacadm/common/llib-lmacadm --- a/usr/src/lib/libmacadm/common/llib-lmacadm Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ -/*PROTOLIB1*/ - -#include diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libmacadm/common/mapfile-vers --- a/usr/src/lib/libmacadm/common/mapfile-vers Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -SUNWprivate_1.1 { - global: - macadm_walk; - local: - *; -}; diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libmacadm/i386/Makefile --- a/usr/src/lib/libmacadm/i386/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#pragma ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libmacadm/sparc/Makefile --- a/usr/src/lib/libmacadm/sparc/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#pragma ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/Makefile --- a/usr/src/lib/libwladm/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include $(SRC)/lib/Makefile.lib - -HDRS = libwladm.h libwladm_impl.h -HDRDIR = common - -SUBDIRS = $(MACH) - -POFILE = libwladm.po -MSGFILES = common/libwladm.c -XGETFLAGS = -a -x libwladm.xcl - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint - -.KEEP_STATE: - -all clean clobber install lint: $(SUBDIRS) - -install_h: $(ROOTHDRS) - -check: $(CHECKHDRS) - -$(POFILE): pofile_MSGFILES - -_msg: $(MSGDOMAINPOFILE) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include $(SRC)/Makefile.msg.targ -include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/Makefile.com --- a/usr/src/lib/libwladm/Makefile.com Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -LIBRARY = libwladm.a -VERS = .1 -OBJECTS = libwladm.o - -include ../../Makefile.lib -# install this library in the root filesystem -include ../../Makefile.rootfs - -LIBS = $(DYNLIB) $(LINTLIB) -LDLIBS += -ldevinfo -lsocket -lc - -SRCDIR = ../common -$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) -D_REENTRANT - -.KEEP_STATE: - -all: $(LIBS) - -lint: lintcheck - -include $(SRC)/lib/Makefile.targ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/common/libwladm.c --- a/usr/src/lib/libwladm/common/libwladm.c Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1962 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct val_desc { - char *vd_name; - uint_t vd_val; -} val_desc_t; - -struct prop_desc; - -typedef wladm_status_t pd_getf_t(int, wldp_t *, char **, uint_t *); -typedef wladm_status_t pd_setf_t(int, wldp_t *, val_desc_t *, uint_t); -typedef wladm_status_t pd_checkf_t(int, wldp_t *, struct prop_desc *, char **, - uint_t, val_desc_t **); -typedef struct prop_desc { - char *pd_name; - val_desc_t pd_defval; - val_desc_t *pd_modval; - uint_t pd_nmodval; - pd_setf_t *pd_set; - pd_getf_t *pd_getmod; - pd_getf_t *pd_get; - pd_checkf_t *pd_check; -} prop_desc_t; - -static int do_get_bsstype(int, wldp_t *); -static int do_get_essid(int, wldp_t *); -static int do_get_bssid(int, wldp_t *); -static int do_get_signal(int, wldp_t *); -static int do_get_encryption(int, wldp_t *); -static int do_get_authmode(int, wldp_t *); -static int do_get_linkstatus(int, wldp_t *); -static int do_get_esslist(int, wldp_t *); -static int do_get_rate(int, wldp_t *); -static int do_get_phyconf(int, wldp_t *); -static int do_get_powermode(int, wldp_t *); -static int do_get_radio(int, wldp_t *); -static int do_get_mode(int, wldp_t *); - -static int do_set_bsstype(int, wldp_t *, wladm_bsstype_t *); -static int do_set_authmode(int, wldp_t *, wladm_auth_t *); -static int do_set_encryption(int, wldp_t *, wladm_secmode_t *); -static int do_set_essid(int, wldp_t *, wladm_essid_t *); -static int do_set_createibss(int, wldp_t *, boolean_t *); -static int do_set_wepkey(int, wldp_t *, wladm_wep_key_t *, uint_t); -static int do_set_rate(int, wldp_t *, wladm_rates_t *); -static int do_set_powermode(int, wldp_t *, wladm_powermode_t *); -static int do_set_radio(int, wldp_t *, wladm_radio_t *); -static int do_set_channel(int, wldp_t *, wladm_channel_t *); - -static int open_link(const char *); -static int do_scan(int, wldp_t *); -static int do_disconnect(int, wldp_t *); -static boolean_t find_val_by_name(const char *, val_desc_t *, uint_t, uint_t *); -static boolean_t find_name_by_val(uint_t, val_desc_t *, uint_t, char **); -static void generate_essid(wladm_essid_t *); - -static wladm_status_t wladm_wlresult2status(wldp_t *); - -static pd_getf_t do_get_rate_mod, do_get_rate_prop, do_get_channel_prop, - do_get_powermode_prop, do_get_radio_prop; -static pd_setf_t do_set_rate_prop, do_set_powermode_prop, - do_set_radio_prop; -static pd_checkf_t do_check_prop, do_check_rate; - -static val_desc_t status_vals[] = { - { "ok", WLADM_STATUS_OK }, - { "invalid argument", WLADM_STATUS_BADARG }, - { "operation failed", WLADM_STATUS_FAILED }, - { "operation not supported", WLADM_STATUS_NOTSUP }, - { "already connected", WLADM_STATUS_ISCONN }, - { "not connected", WLADM_STATUS_NOTCONN }, - { "not found", WLADM_STATUS_NOTFOUND }, - { "value not found", WLADM_STATUS_BADVAL }, - { "invalid link", WLADM_STATUS_LINKINVAL }, - { "insufficient memory", WLADM_STATUS_NOMEM }, - { "operation timed out", WLADM_STATUS_TIMEDOUT }, - { "read-only property", WLADM_STATUS_PROPRDONLY }, - { "not enough space", WLADM_STATUS_TOOSMALL }, - { "invalid number of values", WLADM_STATUS_BADVALCNT } -}; - -static val_desc_t linkstatus_vals[] = { - { "disconnected", WLADM_LINK_STATUS_DISCONNECTED }, - { "connected", WLADM_LINK_STATUS_CONNECTED } -}; - -static val_desc_t secmode_vals[] = { - { "none", WLADM_SECMODE_NONE }, - { "wep", WLADM_SECMODE_WEP } -}; - -static val_desc_t strength_vals[] = { - { "very weak", WLADM_STRENGTH_VERY_WEAK }, - { "weak", WLADM_STRENGTH_WEAK }, - { "good", WLADM_STRENGTH_GOOD }, - { "very good", WLADM_STRENGTH_VERY_GOOD }, - { "excellent", WLADM_STRENGTH_EXCELLENT } -}; - -static val_desc_t mode_vals[] = { - { "a", WLADM_MODE_80211A }, - { "b", WLADM_MODE_80211B }, - { "g", WLADM_MODE_80211G }, -}; - -static val_desc_t auth_vals[] = { - { "open", WLADM_AUTH_OPEN }, - { "shared", WLADM_AUTH_SHARED } -}; - -static val_desc_t bsstype_vals[] = { - { "bss", WLADM_BSSTYPE_BSS }, - { "ibss", WLADM_BSSTYPE_IBSS }, - { "any", WLADM_BSSTYPE_ANY } -}; - -static val_desc_t radio_vals[] = { - { "on", WLADM_RADIO_ON }, - { "off", WLADM_RADIO_OFF } -}; - -static val_desc_t powermode_vals[] = { - { "off", WLADM_PM_OFF }, - { "fast", WLADM_PM_FAST }, - { "max", WLADM_PM_MAX } -}; - -#define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) -static prop_desc_t prop_table[] = { - - { "channel", { NULL, 0 }, NULL, 0, - NULL, NULL, do_get_channel_prop, do_check_prop}, - - { "powermode", { "off", WLADM_PM_OFF }, powermode_vals, - VALCNT(powermode_vals), - do_set_powermode_prop, NULL, - do_get_powermode_prop, do_check_prop}, - - { "radio", { "on", WLADM_RADIO_ON }, radio_vals, - VALCNT(radio_vals), - do_set_radio_prop, NULL, - do_get_radio_prop, do_check_prop}, - - { "speed", { "", 0 }, NULL, 0, - do_set_rate_prop, do_get_rate_mod, - do_get_rate_prop, do_check_rate} -}; -/* - * Unfortunately, MAX_SCAN_SUPPORT_RATES is too small to allow all - * rates to be retrieved. However, we cannot increase it at this - * time because it will break binary comatibility with unbundled - * WiFi drivers and utilities. So for now we define an additional - * constant, MAX_SUPPORT_RATES, to allow all rates to be retrieved. - */ -#define MAX_SUPPORT_RATES 64 -#define WLADM_MAX_PROPS (sizeof (prop_table) / sizeof (prop_desc_t)) -#define IS_CONNECTED(gbuf) \ - ((*(wl_linkstatus_t *)((gbuf)->wldp_buf) == WL_CONNECTED)) - -static wladm_status_t -wladm_wlresult2status(wldp_t *gbuf) -{ - switch (gbuf->wldp_result) { - case WL_SUCCESS: - return (WLADM_STATUS_OK); - - case WL_NOTSUPPORTED: - case WL_LACK_FEATURE: - return (WLADM_STATUS_NOTSUP); - - case WL_READONLY: - return (WLADM_STATUS_PROPRDONLY); - - default: - break; - } - - return (WLADM_STATUS_FAILED); -} - -static int -open_link(const char *link) -{ - char linkname[MAXPATHLEN]; - wldp_t *gbuf; - int fd; - - if (link == NULL) - return (-1); - - (void) snprintf(linkname, MAXPATHLEN, "/dev/%s", link); - if ((fd = open(linkname, O_RDWR)) < 0) - return (-1); - - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - (void) close(fd); - return (-1); - } - - /* - * Check to see if the link is wireless. - */ - if (do_get_bsstype(fd, gbuf) < 0) { - free(gbuf); - (void) close(fd); - return (-1); - } - - free(gbuf); - return (fd); -} - -static wladm_mode_t -do_convert_mode(wl_phy_conf_t *phyp) -{ - switch (phyp->wl_phy_fhss_conf.wl_fhss_subtype) { - case WL_ERP: - return (WLADM_MODE_80211G); - case WL_OFDM: - return (WLADM_MODE_80211A); - case WL_DSSS: - case WL_FHSS: - return (WLADM_MODE_80211B); - default: - break; - } - - return (WLADM_MODE_NONE); -} - -static boolean_t -do_convert_chan(wl_phy_conf_t *phyp, uint32_t *channelp) -{ - wl_fhss_t *wlfp = &phyp->wl_phy_fhss_conf; - wl_ofdm_t *wlop = &phyp->wl_phy_ofdm_conf; - - switch (wlfp->wl_fhss_subtype) { - case WL_FHSS: - case WL_DSSS: - case WL_IRBASE: - case WL_HRDS: - case WL_ERP: - *channelp = wlfp->wl_fhss_channel; - break; - case WL_OFDM: - *channelp = WLADM_OFDM2CHAN(wlop->wl_ofdm_frequency); - break; - default: - return (B_FALSE); - } - return (B_TRUE); -} - -#define IEEE80211_RATE 0x7f -static void -fill_wlan_attr(wl_ess_conf_t *wlp, wladm_wlan_attr_t *attrp) -{ - int i; - - (void) memset(attrp, 0, sizeof (*attrp)); - - (void) snprintf(attrp->wa_essid.we_bytes, WLADM_MAX_ESSID_LEN, "%s", - wlp->wl_ess_conf_essid.wl_essid_essid); - attrp->wa_valid |= WLADM_WLAN_ATTR_ESSID; - - (void) memcpy(attrp->wa_bssid.wb_bytes, wlp->wl_ess_conf_bssid, - WLADM_BSSID_LEN); - attrp->wa_valid |= WLADM_WLAN_ATTR_BSSID; - - attrp->wa_secmode = (wlp->wl_ess_conf_wepenabled == - WL_ENC_WEP ? WLADM_SECMODE_WEP : WLADM_SECMODE_NONE); - attrp->wa_valid |= WLADM_WLAN_ATTR_SECMODE; - - attrp->wa_bsstype = (wlp->wl_ess_conf_bsstype == WL_BSS_BSS ? - WLADM_BSSTYPE_BSS : WLADM_BSSTYPE_IBSS); - attrp->wa_valid |= WLADM_WLAN_ATTR_BSSTYPE; - - attrp->wa_auth = (wlp->wl_ess_conf_authmode == 0 ? - WLADM_AUTH_OPEN : WLADM_AUTH_SHARED); - attrp->wa_valid |= WLADM_WLAN_ATTR_AUTH; - - attrp->wa_strength = WLADM_SIGNAL2STRENGTH(wlp->wl_ess_conf_sl); - attrp->wa_valid |= WLADM_WLAN_ATTR_STRENGTH; - - attrp->wa_mode = do_convert_mode((wl_phy_conf_t *)&wlp->wl_phy_conf); - attrp->wa_valid |= WLADM_WLAN_ATTR_MODE; - - for (i = 0; i < MAX_SCAN_SUPPORT_RATES; i++) { - wlp->wl_supported_rates[i] &= IEEE80211_RATE; - if (wlp->wl_supported_rates[i] > attrp->wa_speed) - attrp->wa_speed = wlp->wl_supported_rates[i]; - } - if (attrp->wa_speed > 0) - attrp->wa_valid |= WLADM_WLAN_ATTR_SPEED; - - if (do_convert_chan((wl_phy_conf_t *)&wlp->wl_phy_conf, - &attrp->wa_channel)) - attrp->wa_valid |= WLADM_WLAN_ATTR_CHANNEL; -} - -wladm_status_t -wladm_scan(const char *link, void *arg, - boolean_t (*func)(void *, wladm_wlan_attr_t *)) -{ - int fd, i; - uint32_t count; - wl_ess_conf_t *wlp; - wldp_t *gbuf; - wladm_wlan_attr_t wlattr; - wladm_status_t status; - boolean_t connected; - - if ((fd = open_link(link)) < 0) - return (WLADM_STATUS_LINKINVAL); - - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = WLADM_STATUS_NOMEM; - goto done; - } - - if (do_get_linkstatus(fd, gbuf) < 0) { - status = WLADM_STATUS_FAILED; - goto done; - } - connected = IS_CONNECTED(gbuf); - - if (do_scan(fd, gbuf) < 0) { - status = WLADM_STATUS_FAILED; - goto done; - } - - if (do_get_esslist(fd, gbuf) < 0) { - status = WLADM_STATUS_FAILED; - goto done; - } - - wlp = ((wl_ess_list_t *)gbuf->wldp_buf)->wl_ess_list_ess; - count = ((wl_ess_list_t *)(gbuf->wldp_buf))->wl_ess_list_num; - - for (i = 0; i < count; i++, wlp++) { - fill_wlan_attr(wlp, &wlattr); - if (!func(arg, &wlattr)) - break; - } - - if (!connected) { - if (do_get_linkstatus(fd, gbuf) < 0) { - status = WLADM_STATUS_FAILED; - goto done; - } - if (IS_CONNECTED(gbuf)) - (void) do_disconnect(fd, gbuf); - } - - status = WLADM_STATUS_OK; -done: - free(gbuf); - (void) close(fd); - return (status); -} - -/* - * Structures used in building the list of eligible WLANs to connect to. - * Specifically, `connect_state' has the WLAN attributes that must be matched - * (in `cs_attr') and a growing list of WLANs that matched those attributes - * chained through `cs_list'. Each element in the list is of type `attr_node' - * and has the matching WLAN's attributes and a pointer to the next element. - * For convenience, `cs_count' tracks the number of elements in the list. - */ -typedef struct attr_node { - wladm_wlan_attr_t an_attr; - struct attr_node *an_next; -} attr_node_t; - -typedef struct connect_state { - wladm_wlan_attr_t *cs_attr; - uint_t cs_count; - attr_node_t *cs_list; -} connect_state_t; - -/* - * Compare two sets of WLAN attributes. For now, we only consider strength - * and speed (in that order), which matches the documented default policy for - * wladm_connect(). - */ -static int -attr_compare(const void *p1, const void *p2) -{ - wladm_wlan_attr_t *attrp1, *attrp2; - - attrp1 = (*(wladm_wlan_attr_t **)p1); - attrp2 = (*(wladm_wlan_attr_t **)p2); - - if (attrp1->wa_strength < attrp2->wa_strength) - return (1); - - if (attrp1->wa_strength > attrp2->wa_strength) - return (-1); - - return (attrp2->wa_speed - attrp1->wa_speed); -} - -/* - * Callback function used by wladm_connect() to filter out unwanted WLANs when - * scanning for available WLANs. Always returns B_TRUE to continue the scan. - */ -static boolean_t -connect_cb(void *arg, wladm_wlan_attr_t *attrp) -{ - attr_node_t *nodep; - wladm_wlan_attr_t *fattrp; - connect_state_t *statep = (connect_state_t *)arg; - - fattrp = statep->cs_attr; - if (fattrp == NULL) - goto append; - - if ((fattrp->wa_valid & attrp->wa_valid) != fattrp->wa_valid) - return (B_TRUE); - - if ((fattrp->wa_valid & WLADM_WLAN_ATTR_ESSID) != 0 && - strncmp(fattrp->wa_essid.we_bytes, attrp->wa_essid.we_bytes, - WLADM_MAX_ESSID_LEN) != 0) - return (B_TRUE); - - if ((fattrp->wa_valid & WLADM_WLAN_ATTR_SECMODE) != 0 && - fattrp->wa_secmode != attrp->wa_secmode) - return (B_TRUE); - - if ((fattrp->wa_valid & WLADM_WLAN_ATTR_MODE) != 0 && - fattrp->wa_mode != attrp->wa_mode) - return (B_TRUE); - - if ((fattrp->wa_valid & WLADM_WLAN_ATTR_STRENGTH) != 0 && - fattrp->wa_strength != attrp->wa_strength) - return (B_TRUE); - - if ((fattrp->wa_valid & WLADM_WLAN_ATTR_SPEED) != 0 && - fattrp->wa_speed != attrp->wa_speed) - return (B_TRUE); - - if ((fattrp->wa_valid & WLADM_WLAN_ATTR_AUTH) != 0) { - attrp->wa_auth = fattrp->wa_auth; - attrp->wa_valid |= WLADM_WLAN_ATTR_AUTH; - } - - if ((fattrp->wa_valid & WLADM_WLAN_ATTR_BSSTYPE) != 0 && - fattrp->wa_bsstype != attrp->wa_bsstype) - return (B_TRUE); - - if ((fattrp->wa_valid & WLADM_WLAN_ATTR_BSSID) != 0 && - memcmp(fattrp->wa_bssid.wb_bytes, attrp->wa_bssid.wb_bytes, - WLADM_BSSID_LEN) != 0) - return (B_TRUE); -append: - nodep = malloc(sizeof (attr_node_t)); - if (nodep == NULL) - return (B_TRUE); - - (void) memcpy(&nodep->an_attr, attrp, sizeof (wladm_wlan_attr_t)); - nodep->an_next = statep->cs_list; - statep->cs_list = nodep; - statep->cs_count++; - - return (B_TRUE); -} - -static wladm_status_t -do_connect(int fd, wldp_t *gbuf, wladm_wlan_attr_t *attrp, - boolean_t create_ibss, void *keys, uint_t key_count, int timeout) -{ - wladm_secmode_t secmode; - wladm_auth_t authmode; - wladm_bsstype_t bsstype; - wladm_essid_t essid; - boolean_t essid_valid = B_FALSE; - wladm_channel_t channel; - hrtime_t start; - - if ((attrp->wa_valid & WLADM_WLAN_ATTR_CHANNEL) != 0) { - channel = attrp->wa_channel; - if (do_set_channel(fd, gbuf, &channel) < 0) - goto fail; - } - - secmode = ((attrp->wa_valid & WLADM_WLAN_ATTR_SECMODE) != 0) ? - attrp->wa_secmode : WLADM_SECMODE_NONE; - - if (do_set_encryption(fd, gbuf, &secmode) < 0) - goto fail; - - authmode = ((attrp->wa_valid & WLADM_WLAN_ATTR_AUTH) != 0) ? - attrp->wa_auth : WLADM_AUTH_OPEN; - - if (do_set_authmode(fd, gbuf, &authmode) < 0) - goto fail; - - bsstype = ((attrp->wa_valid & WLADM_WLAN_ATTR_BSSTYPE) != 0) ? - attrp->wa_bsstype : WLADM_BSSTYPE_BSS; - - if (do_set_bsstype(fd, gbuf, &bsstype) < 0) - goto fail; - - if (secmode == WLADM_SECMODE_WEP) { - if (keys == NULL || key_count == 0 || key_count > MAX_NWEPKEYS) - return (WLADM_STATUS_BADARG); - if (do_set_wepkey(fd, gbuf, keys, key_count) < 0) - goto fail; - } - - if (create_ibss) { - if (do_set_channel(fd, gbuf, &channel) < 0) - goto fail; - - if (do_set_createibss(fd, gbuf, &create_ibss) < 0) - goto fail; - - if ((attrp->wa_valid & WLADM_WLAN_ATTR_ESSID) == 0) { - generate_essid(&essid); - essid_valid = B_TRUE; - } - } - - if ((attrp->wa_valid & WLADM_WLAN_ATTR_ESSID) != 0) { - essid = attrp->wa_essid; - essid_valid = B_TRUE; - } - - if (!essid_valid) - return (WLADM_STATUS_FAILED); - if (do_set_essid(fd, gbuf, &essid) < 0) - goto fail; - - start = gethrtime(); - for (;;) { - if (do_get_linkstatus(fd, gbuf) < 0) - goto fail; - - if (IS_CONNECTED(gbuf)) - break; - - (void) poll(NULL, 0, WLADM_CONNECT_POLLRATE); - if ((timeout >= 0) && (gethrtime() - start) / - NANOSEC >= timeout) - return (WLADM_STATUS_TIMEDOUT); - } - return (WLADM_STATUS_OK); -fail: - return (wladm_wlresult2status(gbuf)); -} - -wladm_status_t -wladm_connect(const char *link, wladm_wlan_attr_t *attrp, - int timeout, void *keys, uint_t key_count, uint_t flags) -{ - int fd, i; - wldp_t *gbuf = NULL; - connect_state_t state = {0, NULL, NULL}; - attr_node_t *nodep = NULL; - boolean_t create_ibss, set_authmode; - wladm_wlan_attr_t **wl_list = NULL; - wladm_status_t status = WLADM_STATUS_FAILED; - - if ((fd = open_link(link)) < 0) - return (WLADM_STATUS_LINKINVAL); - - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = WLADM_STATUS_NOMEM; - goto done; - } - - if (do_get_linkstatus(fd, gbuf) < 0) { - status = WLADM_STATUS_FAILED; - goto done; - } - - if (IS_CONNECTED(gbuf)) { - status = WLADM_STATUS_ISCONN; - goto done; - } - - set_authmode = ((attrp != NULL) && - (attrp->wa_valid & WLADM_WLAN_ATTR_MODE) != 0); - create_ibss = ((flags & WLADM_OPT_CREATEIBSS) != 0 && - attrp != NULL && - (attrp->wa_valid & WLADM_WLAN_ATTR_BSSTYPE) != 0 && - attrp->wa_bsstype == WLADM_BSSTYPE_IBSS); - - if ((flags & WLADM_OPT_NOSCAN) != 0 || - (create_ibss && attrp != NULL && - (attrp->wa_valid & WLADM_WLAN_ATTR_ESSID) == 0)) { - status = do_connect(fd, gbuf, attrp, - create_ibss, keys, key_count, timeout); - goto done; - } - - state.cs_attr = attrp; - state.cs_list = NULL; - state.cs_count = 0; - - status = wladm_scan(link, &state, connect_cb); - if (status != WLADM_STATUS_OK) - goto done; - - if (state.cs_count == 0) { - if (!create_ibss) { - status = WLADM_STATUS_NOTFOUND; - goto done; - } - status = do_connect(fd, gbuf, attrp, create_ibss, - keys, key_count, timeout); - goto done; - } - - wl_list = malloc(state.cs_count * sizeof (wladm_wlan_attr_t *)); - if (wl_list == NULL) { - status = WLADM_STATUS_NOMEM; - goto done; - } - - nodep = state.cs_list; - for (i = 0; i < state.cs_count; i++) { - wl_list[i] = &nodep->an_attr; - nodep = nodep->an_next; - } - qsort(wl_list, state.cs_count, sizeof (wladm_wlan_attr_t *), - attr_compare); - - for (i = 0; i < state.cs_count; i++) { - wladm_wlan_attr_t *ap = wl_list[i]; - - status = do_connect(fd, gbuf, ap, create_ibss, keys, - key_count, timeout); - if (status == WLADM_STATUS_OK) - break; - - if (!set_authmode) { - ap->wa_auth = WLADM_AUTH_SHARED; - ap->wa_valid |= WLADM_WLAN_ATTR_AUTH; - status = do_connect(fd, gbuf, ap, create_ibss, keys, - key_count, timeout); - if (status == WLADM_STATUS_OK) - break; - } - } -done: - if ((status != WLADM_STATUS_OK) && (status != WLADM_STATUS_ISCONN)) - (void) do_disconnect(fd, gbuf); - - while (state.cs_list != NULL) { - nodep = state.cs_list; - state.cs_list = nodep->an_next; - free(nodep); - } - free(gbuf); - free(wl_list); - (void) close(fd); - return (status); -} - -wladm_status_t -wladm_disconnect(const char *link) -{ - int fd; - wldp_t *gbuf; - wladm_status_t status; - - if ((fd = open_link(link)) < 0) - return (WLADM_STATUS_BADARG); - - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = WLADM_STATUS_NOMEM; - goto done; - } - - if (do_get_linkstatus(fd, gbuf) < 0) { - status = WLADM_STATUS_FAILED; - goto done; - } - - if (!IS_CONNECTED(gbuf)) { - status = WLADM_STATUS_NOTCONN; - goto done; - } - - if (do_disconnect(fd, gbuf) < 0) { - status = WLADM_STATUS_FAILED; - goto done; - } - - if (do_get_linkstatus(fd, gbuf) < 0) { - status = WLADM_STATUS_FAILED; - goto done; - } - - if (IS_CONNECTED(gbuf)) { - status = WLADM_STATUS_FAILED; - goto done; - } - - status = WLADM_STATUS_OK; -done: - free(gbuf); - (void) close(fd); - return (status); -} - -typedef struct wladm_linkname { - char wl_name[MAXNAMELEN]; - struct wladm_linkname *wl_next; -} wladm_linkname_t; - -typedef struct wladm_walk { - wladm_linkname_t *ww_list; - wladm_status_t ww_status; -} wladm_walk_t; - -/* ARGSUSED */ -static int -append_linkname(di_node_t node, di_minor_t minor, void *arg) -{ - wladm_walk_t *statep = arg; - wladm_linkname_t **lastp = &statep->ww_list; - wladm_linkname_t *wlp = *lastp; - char name[MAXNAMELEN]; - - (void) snprintf(name, MAXNAMELEN, "%s%d", - di_driver_name(node), di_instance(node)); - - while (wlp != NULL) { - if (strcmp(wlp->wl_name, name) == 0) - return (DI_WALK_CONTINUE); - - lastp = &wlp->wl_next; - wlp = wlp->wl_next; - } - if ((wlp = malloc(sizeof (*wlp))) == NULL) { - statep->ww_status = WLADM_STATUS_NOMEM; - return (DI_WALK_CONTINUE); - } - - (void) strlcpy(wlp->wl_name, name, MAXNAMELEN); - wlp->wl_next = NULL; - *lastp = wlp; - - return (DI_WALK_CONTINUE); -} - -wladm_status_t -wladm_walk(void *arg, boolean_t (*func)(void *, const char *)) -{ - di_node_t root; - wladm_walk_t state; - wladm_linkname_t *wlp, *wlp_next; - boolean_t cont = B_TRUE; - - if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) - return (WLADM_STATUS_FAILED); - - state.ww_list = NULL; - state.ww_status = WLADM_STATUS_OK; - (void) di_walk_minor(root, DDI_NT_NET_WIFI, DI_CHECK_ALIAS, - &state, append_linkname); - di_fini(root); - - for (wlp = state.ww_list; wlp != NULL; wlp = wlp_next) { - /* - * NOTE: even if (*func)() returns B_FALSE, the loop continues - * since all memory must be freed. - */ - if (cont) - cont = (*func)(arg, wlp->wl_name); - wlp_next = wlp->wl_next; - free(wlp); - } - return (state.ww_status); -} - -wladm_status_t -wladm_get_link_attr(const char *link, wladm_link_attr_t *attrp) -{ - int fd; - wldp_t *gbuf; - wl_rssi_t signal; - wl_bss_type_t bsstype; - wl_authmode_t authmode; - wl_encryption_t encryption; - wl_rates_t *ratesp; - wladm_wlan_attr_t *wl_attrp; - wladm_status_t status = WLADM_STATUS_FAILED; - - if (attrp == NULL) - return (WLADM_STATUS_BADARG); - - if ((fd = open_link(link)) < 0) - return (WLADM_STATUS_LINKINVAL); - - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = WLADM_STATUS_NOMEM; - goto done; - } - - (void) memset(attrp, 0, sizeof (*attrp)); - wl_attrp = &attrp->la_wlan_attr; - - if (do_get_linkstatus(fd, gbuf) < 0) - goto done; - - attrp->la_valid |= WLADM_LINK_ATTR_STATUS; - if (!IS_CONNECTED(gbuf)) { - attrp->la_status = WLADM_LINK_STATUS_DISCONNECTED; - status = WLADM_STATUS_OK; - goto done; - } - attrp->la_status = WLADM_LINK_STATUS_CONNECTED; - - if (do_get_essid(fd, gbuf) < 0) - goto done; - - (void) strlcpy(wl_attrp->wa_essid.we_bytes, - ((wl_essid_t *)(gbuf->wldp_buf))->wl_essid_essid, - WLADM_MAX_ESSID_LEN); - - wl_attrp->wa_valid |= WLADM_WLAN_ATTR_ESSID; - - if (do_get_bssid(fd, gbuf) < 0) - goto done; - - (void) memcpy(wl_attrp->wa_bssid.wb_bytes, gbuf->wldp_buf, - WLADM_BSSID_LEN); - - wl_attrp->wa_valid |= WLADM_WLAN_ATTR_BSSID; - - if (do_get_encryption(fd, gbuf) < 0) - goto done; - - encryption = *(wl_encryption_t *)(gbuf->wldp_buf); - wl_attrp->wa_valid |= WLADM_WLAN_ATTR_SECMODE; - - switch (encryption) { - case WL_NOENCRYPTION: - wl_attrp->wa_secmode = WLADM_SECMODE_NONE; - break; - case WL_ENC_WEP: - wl_attrp->wa_secmode = WLADM_SECMODE_WEP; - break; - default: - wl_attrp->wa_valid &= ~WLADM_WLAN_ATTR_SECMODE; - break; - } - - if (do_get_signal(fd, gbuf) < 0) - goto done; - - signal = *(wl_rssi_t *)(gbuf->wldp_buf); - wl_attrp->wa_valid |= WLADM_WLAN_ATTR_STRENGTH; - wl_attrp->wa_strength = WLADM_SIGNAL2STRENGTH(signal); - - if (do_get_rate(fd, gbuf) < 0) - goto done; - - ratesp = (wl_rates_t *)(gbuf->wldp_buf); - if (ratesp->wl_rates_num > 0) { - uint_t i, r = 0; - - for (i = 0; i < ratesp->wl_rates_num; i++) { - if (ratesp->wl_rates_rates[i] > r) - r = ratesp->wl_rates_rates[i]; - } - wl_attrp->wa_speed = r; - wl_attrp->wa_valid |= WLADM_WLAN_ATTR_SPEED; - } - - if (do_get_authmode(fd, gbuf) < 0) - goto done; - - authmode = *(wl_authmode_t *)(gbuf->wldp_buf); - wl_attrp->wa_valid |= WLADM_WLAN_ATTR_AUTH; - - switch (authmode) { - case WL_OPENSYSTEM: - wl_attrp->wa_auth = WLADM_AUTH_OPEN; - break; - case WL_SHAREDKEY: - wl_attrp->wa_auth = WLADM_AUTH_SHARED; - break; - default: - wl_attrp->wa_valid &= ~WLADM_WLAN_ATTR_AUTH; - break; - } - - if (do_get_bsstype(fd, gbuf) < 0) - goto done; - - bsstype = *(wl_bss_type_t *)(gbuf->wldp_buf); - wl_attrp->wa_valid |= WLADM_WLAN_ATTR_BSSTYPE; - - switch (bsstype) { - case WL_BSS_BSS: - wl_attrp->wa_bsstype = WLADM_BSSTYPE_BSS; - break; - case WL_BSS_IBSS: - wl_attrp->wa_bsstype = WLADM_BSSTYPE_IBSS; - break; - case WL_BSS_ANY: - wl_attrp->wa_bsstype = WLADM_BSSTYPE_ANY; - break; - default: - wl_attrp->wa_valid &= ~WLADM_WLAN_ATTR_BSSTYPE; - break; - } - - if (do_get_mode(fd, gbuf) < 0) - goto done; - - wl_attrp->wa_mode = do_convert_mode((wl_phy_conf_t *)(gbuf->wldp_buf)); - wl_attrp->wa_valid |= WLADM_WLAN_ATTR_MODE; - if (wl_attrp->wa_mode != WLADM_MODE_NONE) - wl_attrp->wa_valid |= WLADM_WLAN_ATTR_MODE; - - attrp->la_valid |= WLADM_LINK_ATTR_WLAN; - status = WLADM_STATUS_OK; - -done: - free(gbuf); - (void) close(fd); - return (status); -} - -boolean_t -wladm_is_valid(const char *link) -{ - int fd = open_link(link); - - if (fd < 0) - return (B_FALSE); - - (void) close(fd); - return (B_TRUE); -} - -/* ARGSUSED */ -static wladm_status_t -do_check_prop(int fd, wldp_t *guf, prop_desc_t *pdp, char **prop_val, - uint_t val_cnt, val_desc_t **vdpp) -{ - int i; - val_desc_t *vdp; - - if (pdp->pd_nmodval == 0) - return (WLADM_STATUS_PROPRDONLY); - - if (val_cnt != 1) - return (WLADM_STATUS_BADVALCNT); - - for (i = 0; i < pdp->pd_nmodval; i++) - if (strcasecmp(*prop_val, pdp->pd_modval[i].vd_name) == 0) - break; - - if (i == pdp->pd_nmodval) - return (WLADM_STATUS_BADVAL); - - vdp = malloc(sizeof (val_desc_t)); - if (vdp == NULL) - return (WLADM_STATUS_NOMEM); - - (void) memcpy(vdp, &pdp->pd_modval[i], sizeof (val_desc_t)); - *vdpp = vdp; - return (WLADM_STATUS_OK); -} - -static wladm_status_t -do_set_prop(int fd, wldp_t *gbuf, prop_desc_t *pdp, - char **prop_val, uint_t val_cnt) -{ - wladm_status_t status; - val_desc_t *vdp = NULL; - uint_t cnt; - - if (pdp->pd_set == NULL) - return (WLADM_STATUS_PROPRDONLY); - - if (prop_val != NULL) { - status = pdp->pd_check(fd, gbuf, pdp, prop_val, - val_cnt, &vdp); - - if (status != WLADM_STATUS_OK) - return (status); - - cnt = val_cnt; - } else { - if (pdp->pd_defval.vd_name == NULL) - return (WLADM_STATUS_NOTSUP); - - if ((vdp = malloc(sizeof (val_desc_t))) == NULL) - return (WLADM_STATUS_NOMEM); - - *vdp = pdp->pd_defval; - cnt = 1; - } - status = pdp->pd_set(fd, gbuf, vdp, cnt); - if (status == WLADM_STATUS_OK) { - /* - * Some ioctls return 0 but store error code in - * wldp_result. Need to fix them. - */ - if (gbuf->wldp_result != WL_SUCCESS) - status = wladm_wlresult2status(gbuf); - } - free(vdp); - return (status); -} - -wladm_status_t -wladm_set_prop(const char *link, const char *prop_name, - char **prop_val, uint_t val_cnt, char **errprop) -{ - int fd, i; - wldp_t *gbuf = NULL; - boolean_t found = B_FALSE; - wladm_status_t status = WLADM_STATUS_OK; - - if ((prop_name == NULL && prop_val != NULL) || - (prop_val != NULL && val_cnt == 0)) - return (WLADM_STATUS_BADARG); - - if ((fd = open_link(link)) < 0) - return (WLADM_STATUS_LINKINVAL); - - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = WLADM_STATUS_NOMEM; - goto done; - } - - for (i = 0; i < WLADM_MAX_PROPS; i++) { - prop_desc_t *pdp = &prop_table[i]; - wladm_status_t s; - - if (prop_name != NULL && - (strcasecmp(prop_name, pdp->pd_name) != 0)) - continue; - - found = B_TRUE; - s = do_set_prop(fd, gbuf, pdp, prop_val, val_cnt); - - if (prop_name != NULL) { - status = s; - break; - } else { - if (s != WLADM_STATUS_OK && - s != WLADM_STATUS_NOTSUP) { - if (errprop != NULL) - *errprop = pdp->pd_name; - status = s; - break; - } - } - } - if (!found) - status = WLADM_STATUS_NOTFOUND; -done: - free(gbuf); - (void) close(fd); - return (status); -} - -/* ARGSUSED */ -wladm_status_t -wladm_walk_prop(const char *link, void *arg, - boolean_t (*func)(void *, const char *)) -{ - int i; - - for (i = 0; i < WLADM_MAX_PROPS; i++) { - if (!func(arg, prop_table[i].pd_name)) - break; - } - return (WLADM_STATUS_OK); -} - -wladm_status_t -wladm_get_prop(const char *link, wladm_prop_type_t type, const char *prop_name, - char **prop_val, uint_t *val_cnt) -{ - int fd; - int i; - wldp_t *gbuf; - wladm_status_t status; - uint_t cnt; - prop_desc_t *pdp; - - if (prop_val == NULL || val_cnt == NULL || *val_cnt == 0) - return (WLADM_STATUS_BADARG); - - for (i = 0; i < WLADM_MAX_PROPS; i++) - if (strcasecmp(prop_name, prop_table[i].pd_name) == 0) - break; - - if (i == WLADM_MAX_PROPS) - return (WLADM_STATUS_NOTFOUND); - - if ((fd = open_link(link)) < 0) - return (WLADM_STATUS_LINKINVAL); - - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = WLADM_STATUS_NOMEM; - goto done; - } - pdp = &prop_table[i]; - status = WLADM_STATUS_OK; - - switch (type) { - case WLADM_PROP_VAL_CURRENT: - status = pdp->pd_get(fd, gbuf, prop_val, val_cnt); - break; - - case WLADM_PROP_VAL_DEFAULT: - if (pdp->pd_defval.vd_name == NULL) { - status = WLADM_STATUS_NOTSUP; - break; - } - (void) strcpy(*prop_val, pdp->pd_defval.vd_name); - *val_cnt = 1; - break; - - case WLADM_PROP_VAL_MODIFIABLE: - if (pdp->pd_getmod != NULL) { - status = pdp->pd_getmod(fd, gbuf, prop_val, val_cnt); - break; - } - cnt = pdp->pd_nmodval; - if (cnt == 0) { - status = WLADM_STATUS_NOTSUP; - } else if (cnt > *val_cnt) { - status = WLADM_STATUS_TOOSMALL; - } else { - for (i = 0; i < cnt; i++) { - (void) strcpy(prop_val[i], - pdp->pd_modval[i].vd_name); - } - *val_cnt = cnt; - } - break; - default: - status = WLADM_STATUS_BADARG; - break; - } -done: - free(gbuf); - (void) close(fd); - return (status); -} - -static boolean_t -find_val_by_name(const char *str, val_desc_t *vdp, uint_t cnt, uint_t *valp) -{ - int i; - - for (i = 0; i < cnt; i++) { - if (strcasecmp(str, vdp[i].vd_name) == 0) { - *valp = vdp[i].vd_val; - return (B_TRUE); - } - } - return (B_FALSE); -} - -static boolean_t -find_name_by_val(uint_t val, val_desc_t *vdp, uint_t cnt, char **strp) -{ - int i; - - for (i = 0; i < cnt; i++) { - if (val == vdp[i].vd_val) { - *strp = vdp[i].vd_name; - return (B_TRUE); - } - } - return (B_FALSE); -} - -const char * -wladm_essid2str(wladm_essid_t *essid, char *buf) -{ - (void) snprintf(buf, WLADM_STRSIZE, "%s", essid->we_bytes); - return (buf); -} - -const char * -wladm_bssid2str(wladm_bssid_t *bssid, char *buf) -{ - return (_link_ntoa(bssid->wb_bytes, buf, WLADM_BSSID_LEN, IFT_OTHER)); -} - -static const char * -wladm_val2str(uint_t val, val_desc_t *vdp, uint_t cnt, char *buf) -{ - char *s; - - if (!find_name_by_val(val, vdp, cnt, &s)) - s = ""; - - (void) snprintf(buf, WLADM_STRSIZE, "%s", s); - return (buf); -} - -const char * -wladm_secmode2str(wladm_secmode_t *secmode, char *buf) -{ - return (wladm_val2str((uint_t)*secmode, secmode_vals, - VALCNT(secmode_vals), buf)); -} - -const char * -wladm_strength2str(wladm_strength_t *strength, char *buf) -{ - return (wladm_val2str((uint_t)*strength, strength_vals, - VALCNT(strength_vals), buf)); -} - -const char * -wladm_mode2str(wladm_mode_t *mode, char *buf) -{ - return (wladm_val2str((uint_t)*mode, mode_vals, - VALCNT(mode_vals), buf)); -} - -const char * -wladm_speed2str(wladm_speed_t *speed, char *buf) -{ - (void) snprintf(buf, WLADM_STRSIZE, "%.*f", *speed % 2, - (float)(*speed) / 2); - return (buf); -} - -const char * -wladm_auth2str(wladm_auth_t *auth, char *buf) -{ - return (wladm_val2str((uint_t)*auth, auth_vals, - VALCNT(auth_vals), buf)); -} - -const char * -wladm_bsstype2str(wladm_bsstype_t *bsstype, char *buf) -{ - return (wladm_val2str((uint_t)*bsstype, bsstype_vals, - VALCNT(bsstype_vals), buf)); -} - -const char * -wladm_linkstatus2str(wladm_linkstatus_t *linkstatus, char *buf) -{ - return (wladm_val2str((uint_t)*linkstatus, linkstatus_vals, - VALCNT(linkstatus_vals), buf)); -} - -const char * -wladm_status2str(wladm_status_t status, char *buf) -{ - const char *s; - - s = wladm_val2str((uint_t)status, status_vals, - VALCNT(status_vals), buf); - (void) snprintf(buf, WLADM_STRSIZE, "%s", dgettext(TEXT_DOMAIN, s)); - return (buf); -} - -wladm_status_t -wladm_str2essid(const char *str, wladm_essid_t *essid) -{ - if (str[0] == '\0') - return (WLADM_STATUS_BADARG); - - (void) strlcpy(essid->we_bytes, str, WLADM_MAX_ESSID_LEN); - return (WLADM_STATUS_OK); -} - -wladm_status_t -wladm_str2bssid(const char *str, wladm_bssid_t *bssid) -{ - int len; - uchar_t *buf; - - buf = _link_aton(str, &len); - if (buf == NULL) - return (WLADM_STATUS_BADARG); - - if (len != WLADM_BSSID_LEN) { - free(buf); - return (WLADM_STATUS_BADARG); - } - - (void) memcpy(bssid->wb_bytes, buf, len); - free(buf); - return (WLADM_STATUS_OK); -} - -wladm_status_t -wladm_str2secmode(const char *str, wladm_secmode_t *secmode) -{ - uint_t val; - - if (!find_val_by_name(str, secmode_vals, VALCNT(secmode_vals), &val)) - return (WLADM_STATUS_BADARG); - - *secmode = (wladm_secmode_t)val; - return (WLADM_STATUS_OK); -} - -wladm_status_t -wladm_str2strength(const char *str, wladm_strength_t *strength) -{ - uint_t val; - - if (!find_val_by_name(str, strength_vals, VALCNT(strength_vals), &val)) - return (WLADM_STATUS_BADARG); - - *strength = (wladm_strength_t)val; - return (WLADM_STATUS_OK); -} - -wladm_status_t -wladm_str2mode(const char *str, wladm_mode_t *mode) -{ - uint_t val; - - if (!find_val_by_name(str, mode_vals, VALCNT(mode_vals), &val)) - return (WLADM_STATUS_BADARG); - - *mode = (wladm_mode_t)val; - return (WLADM_STATUS_OK); -} - -wladm_status_t -wladm_str2speed(const char *str, wladm_speed_t *speed) -{ - *speed = (wladm_speed_t)(atof(str) * 2); - return (WLADM_STATUS_OK); -} - -wladm_status_t -wladm_str2auth(const char *str, wladm_auth_t *auth) -{ - uint_t val; - - if (!find_val_by_name(str, auth_vals, VALCNT(auth_vals), &val)) - return (WLADM_STATUS_BADARG); - - *auth = (wladm_auth_t)val; - return (WLADM_STATUS_OK); -} - -wladm_status_t -wladm_str2bsstype(const char *str, wladm_bsstype_t *bsstype) -{ - uint_t val; - - if (!find_val_by_name(str, bsstype_vals, VALCNT(bsstype_vals), &val)) - return (WLADM_STATUS_BADARG); - - *bsstype = (wladm_bsstype_t)val; - return (WLADM_STATUS_OK); -} - -wladm_status_t -wladm_str2linkstatus(const char *str, wladm_linkstatus_t *linkstatus) -{ - uint_t val; - - if (!find_val_by_name(str, linkstatus_vals, VALCNT(linkstatus_vals), - &val)) - return (WLADM_STATUS_BADARG); - - *linkstatus = (wladm_linkstatus_t)val; - return (WLADM_STATUS_OK); -} - -static int -do_ioctl(int fd, wldp_t *gbuf, uint_t id, size_t len, uint_t cmd, size_t cmdlen) -{ - int rc; - struct strioctl stri; - - gbuf->wldp_type = NET_802_11; - gbuf->wldp_id = id; - gbuf->wldp_length = len; - - stri.ic_timout = 0; - stri.ic_dp = (char *)gbuf; - stri.ic_cmd = cmd; - stri.ic_len = cmdlen; - - if ((rc = ioctl(fd, I_STR, &stri)) != 0) { - if (rc > 0) - errno = rc; - return (-1); - } - return (0); -} - -static int -do_get_ioctl(int fd, wldp_t *gbuf, uint_t id) -{ - (void) memset(gbuf, 0, MAX_BUF_LEN); - return (do_ioctl(fd, gbuf, id, MAX_BUF_LEN, WLAN_GET_PARAM, - MAX_BUF_LEN)); -} - -static int -do_set_ioctl(int fd, wldp_t *gbuf, uint_t id, void *buf, uint_t buflen) -{ - (void) memset(gbuf, 0, MAX_BUF_LEN); - (void) memcpy(gbuf->wldp_buf, buf, buflen); - buflen += WIFI_BUF_OFFSET; - return (do_ioctl(fd, gbuf, id, buflen, WLAN_SET_PARAM, buflen)); -} - -static int -do_cmd_ioctl(int fd, wldp_t *gbuf, uint_t cmd) -{ - (void) memset(gbuf, 0, MAX_BUF_LEN); - return (do_ioctl(fd, gbuf, cmd, sizeof (wldp_t), WLAN_COMMAND, - sizeof (wldp_t))); -} - -static int -do_scan(int fd, wldp_t *gbuf) -{ - return (do_cmd_ioctl(fd, gbuf, WL_SCAN)); -} - -static int -do_disconnect(int fd, wldp_t *gbuf) -{ - return (do_cmd_ioctl(fd, gbuf, WL_DISASSOCIATE)); -} - -static int -do_get_esslist(int fd, wldp_t *gbuf) -{ - (void) memset(gbuf, 0, MAX_BUF_LEN); - return (do_ioctl(fd, gbuf, WL_ESS_LIST, MAX_BUF_LEN, - WLAN_GET_PARAM, sizeof (wldp_t))); -} - -static int -do_get_bssid(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_BSSID)); -} - -static int -do_get_essid(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_ESSID)); -} - -static int -do_get_bsstype(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_BSS_TYPE)); -} - -static int -do_get_linkstatus(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_LINKSTATUS)); -} - -static int -do_get_rate(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_DESIRED_RATES)); -} - -static int -do_get_phyconf(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_PHY_CONFIG)); -} - -static int -do_get_powermode(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_POWER_MODE)); -} - -static int -do_get_radio(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_RADIO)); -} - -static int -do_get_authmode(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_AUTH_MODE)); -} - -static int -do_get_encryption(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_ENCRYPTION)); -} - -static int -do_get_signal(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_RSSI)); -} - -static int -do_get_mode(int fd, wldp_t *gbuf) -{ - return (do_get_ioctl(fd, gbuf, WL_PHY_CONFIG)); -} - -static wladm_status_t -do_get_rate_common(wldp_t *gbuf, char **prop_val, uint_t *val_cnt) -{ - wl_rates_t *wrp = (wl_rates_t *)gbuf->wldp_buf; - uint_t cnt = wrp->wl_rates_num; - uint_t i; - - if (cnt > *val_cnt) - return (WLADM_STATUS_TOOSMALL); - if (wrp->wl_rates_rates[0] == 0) { - prop_val[0][0] = '\0'; - *val_cnt = 1; - return (WLADM_STATUS_OK); - } - - for (i = 0; i < cnt; i++) { - (void) snprintf(prop_val[i], WLADM_STRSIZE, "%.*f", - wrp->wl_rates_rates[i] % 2, - (float)wrp->wl_rates_rates[i] / 2); - } - *val_cnt = cnt; - return (WLADM_STATUS_OK); -} - -static wladm_status_t -do_get_rate_prop(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) -{ - if (do_get_rate(fd, gbuf) < 0) - return (wladm_wlresult2status(gbuf)); - - return (do_get_rate_common(gbuf, prop_val, val_cnt)); -} - -static wladm_status_t -do_get_rate_mod(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) -{ - if (do_get_ioctl(fd, gbuf, WL_SUPPORTED_RATES) < 0) - return (WLADM_STATUS_FAILED); - - return (do_get_rate_common(gbuf, prop_val, val_cnt)); -} - -static wladm_status_t -do_get_channel_prop(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) -{ - uint32_t channel; - - if (do_get_phyconf(fd, gbuf) < 0) - return (wladm_wlresult2status(gbuf)); - - if (!do_convert_chan((wl_phy_conf_t *)gbuf->wldp_buf, &channel)) - return (WLADM_STATUS_NOTFOUND); - - (void) snprintf(*prop_val, WLADM_STRSIZE, "%u", channel); - *val_cnt = 1; - - return (WLADM_STATUS_OK); -} - -static wladm_status_t -do_get_powermode_prop(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) -{ - wl_ps_mode_t *mode; - const char *s; - - if (do_get_powermode(fd, gbuf) < 0) - return (wladm_wlresult2status(gbuf)); - - mode = (wl_ps_mode_t *)(gbuf->wldp_buf); - switch (mode->wl_ps_mode) { - case WL_PM_AM: - s = "off"; - break; - case WL_PM_MPS: - s = "max"; - break; - case WL_PM_FAST: - s = "fast"; - break; - default: - return (WLADM_STATUS_NOTFOUND); - } - (void) snprintf(*prop_val, WLADM_STRSIZE, "%s", s); - *val_cnt = 1; - - return (WLADM_STATUS_OK); -} - -static wladm_status_t -do_get_radio_prop(int fd, wldp_t *gbuf, char **prop_val, uint_t *val_cnt) -{ - wl_radio_t radio; - const char *s; - - if (do_get_radio(fd, gbuf) < 0) - return (wladm_wlresult2status(gbuf)); - - radio = *(wl_radio_t *)(gbuf->wldp_buf); - switch (radio) { - case B_TRUE: - s = "on"; - break; - case B_FALSE: - s = "off"; - break; - default: - return (WLADM_STATUS_NOTFOUND); - } - (void) snprintf(*prop_val, WLADM_STRSIZE, "%s", s); - *val_cnt = 1; - - return (WLADM_STATUS_OK); -} - -static int -do_set_bsstype(int fd, wldp_t *gbuf, wladm_bsstype_t *bsstype) -{ - wl_bss_type_t ibsstype; - - switch (*bsstype) { - case WLADM_BSSTYPE_BSS: - ibsstype = WL_BSS_BSS; - break; - case WLADM_BSSTYPE_IBSS: - ibsstype = WL_BSS_IBSS; - break; - default: - ibsstype = WL_BSS_ANY; - break; - } - return (do_set_ioctl(fd, gbuf, WL_BSS_TYPE, &ibsstype, - sizeof (ibsstype))); -} - -static int -do_set_authmode(int fd, wldp_t *gbuf, wladm_auth_t *auth) -{ - wl_authmode_t auth_mode; - - switch (*auth) { - case WLADM_AUTH_OPEN: - auth_mode = WL_OPENSYSTEM; - break; - case WLADM_AUTH_SHARED: - auth_mode = WL_SHAREDKEY; - break; - default: - return (-1); - } - return (do_set_ioctl(fd, gbuf, WL_AUTH_MODE, &auth_mode, - sizeof (auth_mode))); -} - -static int -do_set_encryption(int fd, wldp_t *gbuf, wladm_secmode_t *secmode) -{ - wl_encryption_t encryption; - - switch (*secmode) { - case WLADM_SECMODE_NONE: - encryption = WL_NOENCRYPTION; - break; - case WLADM_SECMODE_WEP: - encryption = WL_ENC_WEP; - break; - default: - return (-1); - } - return (do_set_ioctl(fd, gbuf, WL_ENCRYPTION, &encryption, - sizeof (encryption))); -} - -static int -do_set_wepkey(int fd, wldp_t *gbuf, wladm_wep_key_t *keys, uint_t key_count) -{ - int i; - wl_wep_key_t *wkp; - wl_wep_key_tab_t wepkey_tab; - wladm_wep_key_t *kp; - - if (key_count == 0 || key_count > MAX_NWEPKEYS || keys == NULL) - return (-1); - - (void) memset(wepkey_tab, 0, sizeof (wepkey_tab)); - for (i = 0; i < MAX_NWEPKEYS; i++) - wepkey_tab[i].wl_wep_operation = WL_NUL; - - for (i = 0; i < key_count; i++) { - kp = &keys[i]; - if (kp->wk_idx == 0 || kp->wk_idx > MAX_NWEPKEYS) - return (-1); - if (kp->wk_len != WLADM_WEPKEY64_LEN && - kp->wk_len != WLADM_WEPKEY128_LEN) - return (-1); - - wkp = &wepkey_tab[kp->wk_idx - 1]; - wkp->wl_wep_operation = WL_ADD; - wkp->wl_wep_length = kp->wk_len; - (void) memcpy(wkp->wl_wep_key, kp->wk_val, kp->wk_len); - } - - return (do_set_ioctl(fd, gbuf, WL_WEP_KEY_TAB, &wepkey_tab, - sizeof (wepkey_tab))); -} - -static int -do_set_essid(int fd, wldp_t *gbuf, wladm_essid_t *essid) -{ - wl_essid_t iessid; - - (void) memset(&iessid, 0, sizeof (essid)); - - if (essid != NULL && essid->we_bytes[0] != '\0') { - iessid.wl_essid_length = strlen(essid->we_bytes); - (void) strlcpy(iessid.wl_essid_essid, essid->we_bytes, - sizeof (iessid.wl_essid_essid)); - } else { - return (-1); - } - return (do_set_ioctl(fd, gbuf, WL_ESSID, &iessid, sizeof (iessid))); -} - -/* ARGSUSED */ -static wladm_status_t -do_check_rate(int fd, wldp_t *gbuf, prop_desc_t *pdp, char **prop_val, - uint_t val_cnt, val_desc_t **vdpp) -{ - int i; - uint_t modval_cnt = MAX_SUPPORT_RATES; - char *buf, **modval; - wladm_status_t status; - val_desc_t *vdp = NULL; - - if (val_cnt != 1) - return (WLADM_STATUS_BADVALCNT); - - buf = malloc((sizeof (char *) + WLADM_STRSIZE) * - MAX_SUPPORT_RATES); - if (buf == NULL) - goto done; - - modval = (char **)(void *)buf; - for (i = 0; i < MAX_SUPPORT_RATES; i++) { - modval[i] = buf + sizeof (char *) * MAX_SUPPORT_RATES + - i * WLADM_STRSIZE; - } - - status = do_get_rate_mod(fd, gbuf, modval, &modval_cnt); - if (status != WLADM_STATUS_OK) - goto done; - - vdp = malloc(sizeof (val_desc_t)); - if (vdp == NULL) { - status = WLADM_STATUS_NOMEM; - goto done; - } - - for (i = 0; i < modval_cnt; i++) { - if (strcasecmp(*prop_val, modval[i]) == 0) { - vdp->vd_val = (uint_t)(atof(*prop_val) * 2); - status = WLADM_STATUS_OK; - *vdpp = vdp; - vdp = NULL; - break; - } - } - if (i == modval_cnt) - status = WLADM_STATUS_BADVAL; -done: - free(buf); - free(vdp); - return (status); -} - -static wladm_status_t -do_set_rate_prop(int fd, wldp_t *gbuf, val_desc_t *vdp, uint_t val_cnt) -{ - wladm_rates_t rates; - - if (val_cnt != 1) - return (WLADM_STATUS_BADVALCNT); - - rates.wr_cnt = 1; - rates.wr_rates[0] = vdp[0].vd_val; - - if (do_set_rate(fd, gbuf, &rates) < 0) - return (wladm_wlresult2status(gbuf)); - - return (WLADM_STATUS_OK); -} - -static int -do_set_rate(int fd, wldp_t *gbuf, wladm_rates_t *rates) -{ - int i; - uint_t len; - wl_rates_t *wrp = (wl_rates_t *)gbuf->wldp_buf; - - (void) memset(gbuf, 0, MAX_BUF_LEN); - - for (i = 0; i < rates->wr_cnt; i++) - wrp->wl_rates_rates[i] = rates->wr_rates[i]; - wrp->wl_rates_num = rates->wr_cnt; - - len = offsetof(wl_rates_t, wl_rates_rates) + - (rates->wr_cnt * sizeof (char)) + WIFI_BUF_OFFSET; - return (do_ioctl(fd, gbuf, WL_DESIRED_RATES, len, WLAN_SET_PARAM, len)); -} - -/* ARGSUSED */ -static wladm_status_t -do_set_powermode_prop(int fd, wldp_t *gbuf, val_desc_t *vdp, uint_t val_cnt) -{ - wladm_powermode_t powermode = (wladm_powermode_t)vdp->vd_val; - - if (do_set_powermode(fd, gbuf, &powermode) < 0) - return (wladm_wlresult2status(gbuf)); - - return (WLADM_STATUS_OK); -} - -static int -do_set_powermode(int fd, wldp_t *gbuf, wladm_powermode_t *pm) -{ - wl_ps_mode_t ps_mode; - - (void) memset(&ps_mode, 0xff, sizeof (ps_mode)); - - switch (*pm) { - case WLADM_PM_OFF: - ps_mode.wl_ps_mode = WL_PM_AM; - break; - case WLADM_PM_MAX: - ps_mode.wl_ps_mode = WL_PM_MPS; - break; - case WLADM_PM_FAST: - ps_mode.wl_ps_mode = WL_PM_FAST; - break; - default: - return (-1); - } - return (do_set_ioctl(fd, gbuf, WL_POWER_MODE, &ps_mode, - sizeof (ps_mode))); -} - -/* ARGSUSED */ -static wladm_status_t -do_set_radio_prop(int fd, wldp_t *gbuf, val_desc_t *vdp, uint_t val_cnt) -{ - wladm_radio_t radio = (wladm_radio_t)vdp->vd_val; - - if (do_set_radio(fd, gbuf, &radio) < 0) - return (wladm_wlresult2status(gbuf)); - - return (WLADM_STATUS_OK); -} - -static int -do_set_radio(int fd, wldp_t *gbuf, wladm_radio_t *radio) -{ - wl_radio_t r; - - switch (*radio) { - case WLADM_RADIO_ON: - r = B_TRUE; - break; - case WLADM_RADIO_OFF: - r = B_FALSE; - break; - default: - return (-1); - } - return (do_set_ioctl(fd, gbuf, WL_RADIO, &r, sizeof (r))); -} - -static int -do_set_channel(int fd, wldp_t *gbuf, wladm_channel_t *channel) -{ - wl_phy_conf_t phy_conf; - - if (*channel > MAX_CHANNEL_NUM) - return (-1); - - (void) memset(&phy_conf, 0xff, sizeof (phy_conf)); - phy_conf.wl_phy_dsss_conf.wl_dsss_channel = *channel; - - return (do_set_ioctl(fd, gbuf, WL_PHY_CONFIG, &phy_conf, - sizeof (phy_conf))); -} - -static int -do_set_createibss(int fd, wldp_t *gbuf, boolean_t *create_ibss) -{ - wl_create_ibss_t cr = (wl_create_ibss_t)(*create_ibss); - - return (do_set_ioctl(fd, gbuf, WL_CREATE_IBSS, &cr, sizeof (cr))); -} - -static void -generate_essid(wladm_essid_t *essid) -{ - srandom(gethrtime()); - (void) snprintf(essid->we_bytes, WLADM_MAX_ESSID_LEN, "%d", random()); -} diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/common/libwladm.h --- a/usr/src/lib/libwladm/common/libwladm.h Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,209 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _LIBWLADM_H -#define _LIBWLADM_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include - -/* - * General libwladm definitions and functions. - * - * These interfaces are ON consolidation-private. - * For documentation, refer to PSARC/2006/623. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define WLADM_MAX_ESSID_LEN 32 /* per 802.11 spec */ -#define WLADM_BSSID_LEN 6 /* per 802.11 spec */ -#define WLADM_STRSIZE 256 - -#define WLADM_CONNECT_TIMEOUT_DEFAULT 10 -#define WLADM_OPT_CREATEIBSS 0x00000001 -#define WLADM_OPT_NOSCAN 0x00000002 - -typedef struct wladm_essid { - char we_bytes[WLADM_MAX_ESSID_LEN]; -} wladm_essid_t; - -typedef struct wladm_bssid { - uint8_t wb_bytes[WLADM_BSSID_LEN]; -} wladm_bssid_t; - -typedef enum { - WLADM_SECMODE_NONE = 1, - WLADM_SECMODE_WEP -} wladm_secmode_t; - -typedef enum { - WLADM_STRENGTH_VERY_WEAK = 1, - WLADM_STRENGTH_WEAK, - WLADM_STRENGTH_GOOD, - WLADM_STRENGTH_VERY_GOOD, - WLADM_STRENGTH_EXCELLENT -} wladm_strength_t; - -typedef enum { - WLADM_MODE_NONE = 0, - WLADM_MODE_80211A, - WLADM_MODE_80211B, - WLADM_MODE_80211G -} wladm_mode_t; - -typedef enum { - WLADM_AUTH_OPEN = 1, - WLADM_AUTH_SHARED -} wladm_auth_t; - -typedef enum { - WLADM_BSSTYPE_BSS = 1, - WLADM_BSSTYPE_IBSS, - WLADM_BSSTYPE_ANY -} wladm_bsstype_t; - -typedef enum { - WLADM_LINK_STATUS_DISCONNECTED = 1, - WLADM_LINK_STATUS_CONNECTED -} wladm_linkstatus_t; - -typedef enum { - WLADM_STATUS_OK = 0, - WLADM_STATUS_BADARG, - WLADM_STATUS_FAILED, - WLADM_STATUS_NOTSUP, - WLADM_STATUS_ISCONN, - WLADM_STATUS_NOTCONN, - WLADM_STATUS_NOTFOUND, - WLADM_STATUS_BADVAL, - WLADM_STATUS_LINKINVAL, - WLADM_STATUS_NOMEM, - WLADM_STATUS_TIMEDOUT, - WLADM_STATUS_PROPRDONLY, - WLADM_STATUS_TOOSMALL, - WLADM_STATUS_BADVALCNT -} wladm_status_t; - -typedef uint32_t wladm_speed_t; -typedef uint32_t wladm_channel_t; - -enum { - WLADM_WLAN_ATTR_ESSID = 0x00000001, - WLADM_WLAN_ATTR_BSSID = 0x00000002, - WLADM_WLAN_ATTR_SECMODE = 0x00000004, - WLADM_WLAN_ATTR_STRENGTH = 0x00000008, - WLADM_WLAN_ATTR_MODE = 0x00000010, - WLADM_WLAN_ATTR_SPEED = 0x00000020, - WLADM_WLAN_ATTR_AUTH = 0x00000040, - WLADM_WLAN_ATTR_BSSTYPE = 0x00000080, - WLADM_WLAN_ATTR_CHANNEL = 0x00000100 -}; -typedef struct wladm_wlan_attr { - uint_t wa_valid; - wladm_essid_t wa_essid; - wladm_bssid_t wa_bssid; - wladm_secmode_t wa_secmode; - wladm_strength_t wa_strength; - wladm_mode_t wa_mode; - wladm_speed_t wa_speed; - wladm_auth_t wa_auth; - wladm_bsstype_t wa_bsstype; - wladm_channel_t wa_channel; -} wladm_wlan_attr_t; - -enum { - WLADM_LINK_ATTR_STATUS = 0x00000001, - WLADM_LINK_ATTR_WLAN = 0x00000002 -}; -typedef struct wladm_link_attr { - uint_t la_valid; - wladm_linkstatus_t la_status; - wladm_wlan_attr_t la_wlan_attr; -} wladm_link_attr_t; - -#define WLADM_WEPKEY64_LEN 5 /* per WEP spec */ -#define WLADM_WEPKEY128_LEN 13 /* per WEP spec */ -#define WLADM_MAX_WEPKEY_LEN 13 /* per WEP spec */ -#define WLADM_MAX_WEPKEYS 4 /* MAX_NWEPKEYS */ -#define WLADM_MAX_WEPKEYNAME_LEN 64 -typedef struct wladm_wep_key { - uint_t wk_idx; - uint_t wk_len; - uint8_t wk_val[WLADM_MAX_WEPKEY_LEN]; - char wk_name[WLADM_MAX_WEPKEYNAME_LEN]; -} wladm_wep_key_t; - -typedef enum { - WLADM_PROP_VAL_CURRENT = 1, - WLADM_PROP_VAL_DEFAULT, - WLADM_PROP_VAL_MODIFIABLE -} wladm_prop_type_t; - -extern wladm_status_t wladm_scan(const char *, void *, - boolean_t (*)(void *, wladm_wlan_attr_t *)); -extern wladm_status_t wladm_connect(const char *, wladm_wlan_attr_t *, - int, void *, uint_t, uint_t); -extern wladm_status_t wladm_disconnect(const char *); -extern wladm_status_t wladm_get_link_attr(const char *, wladm_link_attr_t *); -extern wladm_status_t wladm_walk(void *, boolean_t (*)(void *, const char *)); -extern boolean_t wladm_is_valid(const char *); -extern wladm_status_t wladm_set_prop(const char *, const char *, char **, - uint_t, char **); -extern wladm_status_t wladm_walk_prop(const char *, void *, - boolean_t (*)(void *, const char *)); -extern wladm_status_t wladm_get_prop(const char *, wladm_prop_type_t, - const char *, char **, uint_t *); - -extern const char *wladm_essid2str(wladm_essid_t *, char *); -extern const char *wladm_bssid2str(wladm_bssid_t *, char *); -extern const char *wladm_secmode2str(wladm_secmode_t *, char *); -extern const char *wladm_strength2str(wladm_strength_t *, char *); -extern const char *wladm_mode2str(wladm_mode_t *, char *); -extern const char *wladm_speed2str(wladm_speed_t *, char *); -extern const char *wladm_auth2str(wladm_auth_t *, char *); -extern const char *wladm_bsstype2str(wladm_bsstype_t *, char *); -extern const char *wladm_linkstatus2str(wladm_linkstatus_t *, char *); -extern const char *wladm_status2str(wladm_status_t, char *); - -extern wladm_status_t wladm_str2essid(const char *, wladm_essid_t *); -extern wladm_status_t wladm_str2bssid(const char *, wladm_bssid_t *); -extern wladm_status_t wladm_str2secmode(const char *, wladm_secmode_t *); -extern wladm_status_t wladm_str2strength(const char *, wladm_strength_t *); -extern wladm_status_t wladm_str2mode(const char *, wladm_mode_t *); -extern wladm_status_t wladm_str2speed(const char *, wladm_speed_t *); -extern wladm_status_t wladm_str2auth(const char *, wladm_auth_t *); -extern wladm_status_t wladm_str2bsstype(const char *, wladm_bsstype_t *); -extern wladm_status_t wladm_str2linkstatus(const char *, - wladm_linkstatus_t *); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBWLADM_H */ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/common/libwladm_impl.h --- a/usr/src/lib/libwladm/common/libwladm_impl.h Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _LIBWLADM_IMPL_H -#define _LIBWLADM_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include -#include - -/* - * Implementation-private data structures, macros, and constants. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Map a signal value from 0-15 into an enumerated strength. Since there are - * 5 strengths but 16 values, by convention the "middle" strength gets the - * extra value. Thus, the buckets are 0-2, 3-5, 6-9, 10-12, and 13-15. - */ -#define WLADM_SIGNAL2STRENGTH(signal) \ - (((signal) > 12 ? WLADM_STRENGTH_EXCELLENT : \ - ((signal) > 9 ? WLADM_STRENGTH_VERY_GOOD : \ - ((signal) > 5 ? WLADM_STRENGTH_GOOD : \ - ((signal) > 2 ? WLADM_STRENGTH_WEAK : WLADM_STRENGTH_VERY_WEAK))))) - -/* - * Convert between an OFDM MHz and a channel number. - */ -#define WLADM_OFDM2CHAN(mhz) (((mhz) - 5000) / 5) - -#define WLADM_CONNECT_POLLRATE 200 /* milliseconds */ -#define WLADM_CONNECT_DEFAULT_CHANNEL 1 - -#define WLADM_MAX_RATES 4 -typedef struct wladm_rates { - uint8_t wr_rates[WLADM_MAX_RATES]; - int wr_cnt; -} wladm_rates_t; - -typedef enum { - WLADM_RADIO_ON = 1, - WLADM_RADIO_OFF -} wladm_radio_t; - -typedef enum { - WLADM_PM_OFF = 1, - WLADM_PM_MAX, - WLADM_PM_FAST -} wladm_powermode_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBWLADM_IMPL_H */ diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/common/llib-lwladm --- a/usr/src/lib/libwladm/common/llib-lwladm Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ -/*PROTOLIB1*/ - -#include diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/common/mapfile-vers --- a/usr/src/lib/libwladm/common/mapfile-vers Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -SUNWprivate_1.1 { - global: - wladm_scan; - wladm_connect; - wladm_disconnect; - wladm_get_link_attr; - wladm_walk; - wladm_is_valid; - wladm_set_prop; - wladm_walk_prop; - wladm_get_prop; - wladm_essid2str; - wladm_bssid2str; - wladm_secmode2str; - wladm_strength2str; - wladm_mode2str; - wladm_speed2str; - wladm_auth2str; - wladm_bsstype2str; - wladm_linkstatus2str; - wladm_status2str; - wladm_str2essid; - wladm_str2bssid; - wladm_str2secmode; - wladm_str2strength; - wladm_str2mode; - wladm_str2speed; - wladm_str2auth; - wladm_str2bsstype; - wladm_str2linkstatus; - local: - *; -}; diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/i386/Makefile --- a/usr/src/lib/libwladm/i386/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/libwladm.xcl --- a/usr/src/lib/libwladm/libwladm.xcl Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# -msgid "a" -msgid "b" -msgid "g" -msgid "channel" -msgid "powermode" -msgid "radio" -msgid "speed" -msgid "" -msgid "%.*f" -msgid "%d" -msgid "%s" -msgid "%s%d" -msgid "%u" -msgid "/" -msgid "/dev/%s" -msgid "open" -msgid "shared" -msgid "bss" -msgid "ibss" -msgid "any" -msgid "on" -msgid "off" -msgid "fast" -msgid "max" -msgid "wep" -msgid "none" diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/lib/libwladm/sparc/Makefile --- a/usr/src/lib/libwladm/sparc/Makefile Wed Mar 21 09:33:24 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/pkgdefs/SUNWcslr/prototype_com --- a/usr/src/pkgdefs/SUNWcslr/prototype_com Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/pkgdefs/SUNWcslr/prototype_com Wed Mar 21 09:48:58 2007 -0700 @@ -92,10 +92,8 @@ f none lib/libintl.so.1 755 root bin s none lib/libkstat.so=libkstat.so.1 f none lib/libkstat.so.1 755 root bin -f none lib/liblaadm.so.1 755 root bin f none lib/libld.so.4 755 root bin f none lib/liblddbg.so.4 755 root bin -f none lib/libmacadm.so.1 755 root bin s none lib/libmd.so=libmd.so.1 f none lib/libmd.so.1 755 root bin s none lib/libmd5.so=libmd5.so.1 @@ -151,7 +149,6 @@ s none lib/libtsol.so=libtsol.so.2 s none lib/libw.so=libw.so.1 f none lib/libw.so.1 755 root bin -f none lib/libwladm.so.1 755 root bin s none lib/libumem.so=libumem.so.1 f none lib/libumem.so.1 0755 root bin s none lib/libuuid.so=libuuid.so.1 diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/pkgdefs/etc/exception_list_i386 --- a/usr/src/pkgdefs/etc/exception_list_i386 Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/pkgdefs/etc/exception_list_i386 Wed Mar 21 09:48:58 2007 -0700 @@ -93,22 +93,13 @@ # usr/include/libdladm.h i386 usr/include/libdladm_impl.h i386 -usr/include/liblaadm.h i386 -usr/include/libmacadm.h i386 -usr/include/libwladm.h i386 -usr/include/libwladm_impl.h i386 +usr/include/libdllink.h i386 +usr/include/libdlaggr.h i386 +usr/include/libdlwlan.h i386 +usr/include/libdlwlan_impl.h i386 lib/libdladm.so i386 -lib/liblaadm.so i386 -lib/libmacadm.so i386 -lib/libwladm.so i386 lib/llib-ldladm.ln i386 lib/llib-ldladm i386 -lib/llib-llaadm.ln i386 -lib/llib-llaadm i386 -lib/llib-lmacadm.ln i386 -lib/llib-lmacadm i386 -lib/llib-lwladm.ln i386 -lib/llib-lwladm i386 # # Installed in the proto area for building utilties dependent on # it, but is not shipped. diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/pkgdefs/etc/exception_list_sparc --- a/usr/src/pkgdefs/etc/exception_list_sparc Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/pkgdefs/etc/exception_list_sparc Wed Mar 21 09:48:58 2007 -0700 @@ -82,22 +82,13 @@ # usr/include/libdladm.h sparc usr/include/libdladm_impl.h sparc -usr/include/liblaadm.h sparc -usr/include/libmacadm.h sparc -usr/include/libwladm.h sparc -usr/include/libwladm_impl.h sparc +usr/include/libdllink.h sparc +usr/include/libdlaggr.h sparc +usr/include/libdlwlan.h sparc +usr/include/libdlwlan_impl.h sparc lib/libdladm.so sparc -lib/liblaadm.so sparc -lib/libmacadm.so sparc -lib/libwladm.so sparc lib/llib-ldladm.ln sparc lib/llib-ldladm sparc -lib/llib-llaadm.ln sparc -lib/llib-llaadm sparc -lib/llib-lmacadm.ln sparc -lib/llib-lmacadm sparc -lib/llib-lwladm.ln sparc -lib/llib-lwladm sparc # # Installed in the proto area for building those things # that are dependent on it. No delivered as part of a pkg. diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/tools/scripts/bfu.sh --- a/usr/src/tools/scripts/bfu.sh Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/tools/scripts/bfu.sh Wed Mar 21 09:48:58 2007 -0700 @@ -6527,6 +6527,14 @@ rm -f $usr/kernel/fs/amd64/xmemfs rm -rf $usr/lib/fs/xmemfs + # + # Remove obsolete libmacadm, liblaadm and libwladm. If this is + # a backwards BFU, they will be extracted by cpio. + # + rm -f $root/lib/libmacadm.so.1 + rm -f $root/lib/liblaadm.so.1 + rm -f $root/lib/libwladm.so.1 + # End of pre-archive extraction hacks. if [ $diskless = no -a $zone = global ]; then diff -r b083fcb4e287 -r 5a1dfce6c5cc usr/src/uts/common/io/dld/dld_drv.c --- a/usr/src/uts/common/io/dld/dld_drv.c Wed Mar 21 09:33:24 2007 -0700 +++ b/usr/src/uts/common/io/dld/dld_drv.c Wed Mar 21 09:48:58 2007 -0700 @@ -513,10 +513,12 @@ } if ((err = dls_vlan_setzoneid(dhv->dhv_name, dhv->dhv_zid, - dhv->dhv_docheck)) != 0) + dhv->dhv_docheck)) != 0) { + dls_vlan_rele(dvp); miocnak(q, mp, 0, err); - else + } else { miocack(q, mp, 0, 0); + } } /*