libdladm.c revision a776d98e5f349dbb7f5a47eca48f50e6117adcb7
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * Common Development and Distribution License (the "License").
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * or http://www.opensolaris.org/os/licensing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
f94275ce205810a201404c5f35f4cc96057022b1Adam Leventhal/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum */
187d6ac08adc31ea6868bde0cfbbb288826254e8Matt Ahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <unistd.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <errno.h>
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante#include <ctype.h>
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante#include <fcntl.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <strings.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <dirent.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <stdlib.h>
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby#include <netinet/in.h>
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby#include <arpa/inet.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/param.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/stat.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/dld.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/dld_ioc.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libdladm_impl.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libintl.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libdlpi.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libdllink.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic char dladm_rootdir[MAXPATHLEN] = "/";
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct media_type_desc {
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint32_t media_type;
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define MAX_MEDIA_TYPE_STRING 32
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char media_type_str[MAX_MEDIA_TYPE_STRING];
b1b8ab34de515a5e83206da22c3d7e563241b021lling} media_type_t;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic media_type_t media_type_table[] = {
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_ETHER, "Ethernet" },
990b4856d0eaada6f8140335733a1b1771ed2746lling { DL_WIFI, "WiFi" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_IB, "Infiniband" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_IPV4, "IPv4Tunnel" },
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor { DL_IPV6, "IPv6Tunnel" },
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor { DL_6TO4, "6to4Tunnel" },
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor { DL_CSMACD, "CSMA/CD" },
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor { DL_TPB, "TokenBus" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_TPR, "TokenRing" },
990b4856d0eaada6f8140335733a1b1771ed2746lling { DL_METRO, "MetroNet" },
990b4856d0eaada6f8140335733a1b1771ed2746lling { DL_HDLC, "HDLC" },
990b4856d0eaada6f8140335733a1b1771ed2746lling { DL_CHAR, "SyncCharacter" },
66e2aacc02a4625d105fb249ad16c27e79604ff2gw { DL_CTCA, "CTCA" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_FDDI, "FDDI" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_FC, "FiberChannel" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_ATM, "ATM" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_IPATM, "ATM(ClassicIP)" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_X25, "X.25" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_IPX25, "X.25(ClassicIP)" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_ISDN, "ISDN" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_HIPPI, "HIPPI" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_100VG, "100BaseVGEthernet" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_100VGTPR, "100BaseVGTokenRing" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_ETH_CSMA, "IEEE802.3" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_100BT, "100BaseT" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_FRAME, "FrameRelay" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_MPFRAME, "MPFrameRelay" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_ASYNC, "AsyncCharacter" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_IPNET, "IPNET" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { DL_OTHER, "Other" }
fa9e4066f08beec538e775443c5be79dd423fcabahrens};
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define MEDIATYPECOUNT (sizeof (media_type_table) / sizeof (media_type_t))
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct {
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint32_t lp_type;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *lp_name;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} link_protect_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic link_protect_t link_protect_types[] = {
a3c49ce110f325a563c245bedc4d533adddb7211Albert Lee { MPT_MACNOSPOOF, "mac-nospoof" },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { MPT_RESTRICTED, "restricted" },
66e2aacc02a4625d105fb249ad16c27e79604ff2gw { MPT_IPNOSPOOF, "ip-nospoof" },
66e2aacc02a4625d105fb249ad16c27e79604ff2gw { MPT_DHCPNOSPOOF, "dhcp-nospoof" }
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock};
66e2aacc02a4625d105fb249ad16c27e79604ff2gw#define LPTYPES (sizeof (link_protect_types) / sizeof (link_protect_t))
7b55fa8ea6046becb3b72f8886a503979c322084ck
d0ad202d2eff2cc0c70ee550686a703ddda7106cahrensdladm_status_t
b1b8ab34de515a5e83206da22c3d7e563241b021llingdladm_open(dladm_handle_t *handle)
e7437265dc2a4920c197ed4337665539d358b22cahrens{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int dld_fd;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (handle == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (DLADM_STATUS_BADARG);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((dld_fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0)
a9799022bd90b13722204e80112efaa5bf573099ck return (dladm_errno2status(errno));
a9799022bd90b13722204e80112efaa5bf573099ck
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock /*
3baa08fc5b6bea08a475b0cfe3ad161d74c5864bek * Don't open DLMGMT_DOOR now. dlmgmtd(1M) is not able to
3baa08fc5b6bea08a475b0cfe3ad161d74c5864bek * open the door when the dladm handle is opened because the
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * door hasn't been created yet at that time. Thus, we must
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * open it on-demand in dladm_door_fd(). Move the open()
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens * to dladm_door_fd() for all cases.
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens */
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor if ((*handle = malloc(sizeof (struct dladm_handle))) == NULL) {
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby (void) close(dld_fd);
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby return (DLADM_STATUS_NOMEM);
e09fa4dacfb671e707d50a55ae9b5cc191e1b8cbNeil Perrin }
1d7132005da8d75994a6ad204e6ec05ef5ffaa4bEric Schrock
1d7132005da8d75994a6ad204e6ec05ef5ffaa4bEric Schrock (*handle)->dld_fd = dld_fd;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (*handle)->door_fd = -1;
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante return (DLADM_STATUS_OK);
187d6ac08adc31ea6868bde0cfbbb288826254e8Matt Ahrens}
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrensdladm_close(dladm_handle_t handle)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens{
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if (handle != NULL) {
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens (void) close(handle->dld_fd);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if (handle->door_fd != -1)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens (void) close(handle->door_fd);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens free(handle);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens }
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens}
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensint
990b4856d0eaada6f8140335733a1b1771ed2746llingdladm_dld_fd(dladm_handle_t handle)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
b87f3af36bb994656da117319f5129ddfd05ed21perrin return (handle->dld_fd);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * If DLMGMT_DOOR hasn't been opened in the handle yet, open it.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingdladm_status_t
990b4856d0eaada6f8140335733a1b1771ed2746llingdladm_door_fd(dladm_handle_t handle, int *door_fd)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling int fd;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (handle->door_fd == -1) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((fd = open(DLMGMT_DOOR, O_RDONLY)) < 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (dladm_errno2status(errno));
990b4856d0eaada6f8140335733a1b1771ed2746lling handle->door_fd = fd;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock }
0a4e9518a44f226be6d39383330b5b1792d2f184gw *door_fd = handle->door_fd;
d5b5bb256c576fe5ef26e0795bd40abe77f93246Rich Morris
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (DLADM_STATUS_OK);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick}
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick
485bbbf5450c6645352388d798251c1a89ef4c9cGeorge Wilsonconst char *
485bbbf5450c6645352388d798251c1a89ef4c9cGeorge Wilsondladm_status2str(dladm_status_t status, char *buf)
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson{
990b4856d0eaada6f8140335733a1b1771ed2746lling const char *s;
990b4856d0eaada6f8140335733a1b1771ed2746lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling switch (status) {
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_OK:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "ok";
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_BADARG:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "invalid argument";
7f7322febbcfe774b7270abc3b191c094bfcc517eschrock break;
b1b8ab34de515a5e83206da22c3d7e563241b021lling case DLADM_STATUS_FAILED:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "operation failed";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_TOOSMALL:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "buffer size too small";
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson break;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson case DLADM_STATUS_NOTSUP:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "operation not supported";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson case DLADM_STATUS_NOTFOUND:
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson s = "object not found";
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson break;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson case DLADM_STATUS_BADVAL:
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson s = "invalid value";
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson break;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson case DLADM_STATUS_NOMEM:
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson s = "insufficient memory";
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson break;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson case DLADM_STATUS_EXIST:
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson s = "object already exists";
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson break;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson case DLADM_STATUS_LINKINVAL:
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson s = "invalid link";
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson break;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson case DLADM_STATUS_PROPRDONLY:
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson s = "read-only property";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_BADVALCNT:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "invalid number of values";
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh break;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh case DLADM_STATUS_DBNOTFOUND:
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh s = "database not found";
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh break;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh case DLADM_STATUS_DENIED:
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh s = "permission denied";
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_IOERR:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "I/O error";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_TEMPONLY:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "change cannot be persistent";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_TIMEDOUT:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw s = "operation timed out";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_ISCONN:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "already connected";
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_NOTCONN:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "not connected";
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick break;
4853e976fadf3d55239638b6a1fee20681fde314gw case DLADM_STATUS_REPOSITORYINVAL:
b1b8ab34de515a5e83206da22c3d7e563241b021lling s = "invalid configuration repository";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_MACADDRINVAL:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "invalid MAC address";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_KEYINVAL:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "invalid key";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_INVALIDMACADDRLEN:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "invalid MAC address length";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick case DLADM_STATUS_INVALIDMACADDRTYPE:
b1b8ab34de515a5e83206da22c3d7e563241b021lling s = "invalid MAC address type";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case DLADM_STATUS_LINKBUSY:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "link busy";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case DLADM_STATUS_VIDINVAL:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "invalid VLAN identifier";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case DLADM_STATUS_TRYAGAIN:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "try again later";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case DLADM_STATUS_NONOTIF:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "link notification is not supported";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case DLADM_STATUS_BADTIMEVAL:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "invalid time range";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case DLADM_STATUS_INVALIDMACADDR:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "invalid MAC address value";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case DLADM_STATUS_INVALIDMACADDRNIC:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "MAC address reserved for use by underlying data-link";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case DLADM_STATUS_INVALIDMACADDRINUSE:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "MAC address is already in use";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case DLADM_STATUS_MACFACTORYSLOTINVALID:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "invalid factory MAC address slot";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case DLADM_STATUS_MACFACTORYSLOTUSED:
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire s = "factory MAC address slot already used";
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire break;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright case DLADM_STATUS_MACFACTORYSLOTALLUSED:
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright s = "all factory MAC address slots are in use";
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright break;
a227b7f4f323ad89c40a86c430a5e891504a8e8bhs case DLADM_STATUS_MACFACTORYNOTSUP:
a227b7f4f323ad89c40a86c430a5e891504a8e8bhs s = "factory MAC address slots not supported";
a227b7f4f323ad89c40a86c430a5e891504a8e8bhs break;
a227b7f4f323ad89c40a86c430a5e891504a8e8bhs case DLADM_STATUS_INVALIDMACPREFIX:
a227b7f4f323ad89c40a86c430a5e891504a8e8bhs s = "Invalid MAC address prefix value";
a227b7f4f323ad89c40a86c430a5e891504a8e8bhs break;
e09fa4dacfb671e707d50a55ae9b5cc191e1b8cbNeil Perrin case DLADM_STATUS_INVALIDMACPREFIXLEN:
e09fa4dacfb671e707d50a55ae9b5cc191e1b8cbNeil Perrin s = "Invalid MAC address prefix length";
e09fa4dacfb671e707d50a55ae9b5cc191e1b8cbNeil Perrin break;
e09fa4dacfb671e707d50a55ae9b5cc191e1b8cbNeil Perrin case DLADM_STATUS_BADCPUID:
e09fa4dacfb671e707d50a55ae9b5cc191e1b8cbNeil Perrin s = "non-existent processor ID";
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case DLADM_STATUS_CPUERR:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw s = "could not determine processor status";
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case DLADM_STATUS_CPUNOTONLINE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw s = "processor not online";
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright case DLADM_STATUS_TOOMANYELEMENTS:
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright s = "too many elements specified";
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright break;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright case DLADM_STATUS_BADRANGE:
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright s = "invalid range";
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright break;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright case DLADM_STATUS_DB_NOTFOUND:
3baa08fc5b6bea08a475b0cfe3ad161d74c5864bek s = "database not found";
3baa08fc5b6bea08a475b0cfe3ad161d74c5864bek break;
3baa08fc5b6bea08a475b0cfe3ad161d74c5864bek case DLADM_STATUS_DB_PARSE_ERR:
3baa08fc5b6bea08a475b0cfe3ad161d74c5864bek s = "database parse error";
3baa08fc5b6bea08a475b0cfe3ad161d74c5864bek break;
3baa08fc5b6bea08a475b0cfe3ad161d74c5864bek case DLADM_STATUS_PROP_PARSE_ERR:
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante s = "property parse error";
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante break;
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante case DLADM_STATUS_ATTR_PARSE_ERR:
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante s = "attribute parse error";
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante break;
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante case DLADM_STATUS_FLOW_DB_ERR:
3baa08fc5b6bea08a475b0cfe3ad161d74c5864bek s = "flow database error";
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
99653d4ee642c6528e88224f12409a5f23060994eschrock case DLADM_STATUS_FLOW_DB_OPEN_ERR:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock s = "flow database open error";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_FLOW_DB_PARSE_ERR:
e7437265dc2a4920c197ed4337665539d358b22cahrens s = "flow database parse error";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_FLOWPROP_DB_PARSE_ERR:
e7437265dc2a4920c197ed4337665539d358b22cahrens s = "flow property database parse error";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_FLOW_ADD_ERR:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw s = "flow add error";
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan break;
088f389458728c464569a5506b58070254fa4f7dahrens case DLADM_STATUS_FLOW_WALK_ERR:
bb0ade0978a02d3fe0b0165cd4725fdcb593fbfbahrens s = "flow walk error";
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens break;
d0f3f37e7f24f68fdbd85386c60e576883622762Mark Shellenbaum case DLADM_STATUS_FLOW_IDENTICAL:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens s = "a flow with identical attributes exists";
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor break;
f94275ce205810a201404c5f35f4cc96057022b1Adam Leventhal case DLADM_STATUS_FLOW_INCOMPATIBLE:
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby s = "flow(s) with incompatible attributes exists";
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson break;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick case DLADM_STATUS_FLOW_EXISTS:
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick s = "link still has flows";
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson break;
6e1f5caa9321646aa4212d48e32a0d241866d85dNeil Perrin case DLADM_STATUS_PERSIST_FLOW_EXISTS:
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum s = "persistent flow with the same name exists";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling break;
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens case DLADM_STATUS_INVALID_IP:
6e0cbcaa0c6f2bc34634a4cc17b099f9ecef03d1Matthew Ahrens s = "invalid IP address";
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante break;
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante case DLADM_STATUS_INVALID_PREFIXLEN:
b1b8ab34de515a5e83206da22c3d7e563241b021lling s = "invalid IP prefix length";
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw break;
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor case DLADM_STATUS_INVALID_PROTOCOL:
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens s = "invalid IP protocol";
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens break;
b1b8ab34de515a5e83206da22c3d7e563241b021lling case DLADM_STATUS_INVALID_PORT:
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante s = "invalid port number";
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante break;
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm case DLADM_STATUS_INVALID_DSF:
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm s = "invalid dsfield";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm case DLADM_STATUS_INVALID_DSFMASK:
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm s = "invalid dsfield mask";
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm break;
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm case DLADM_STATUS_INVALID_MACMARGIN:
e7437265dc2a4920c197ed4337665539d358b22cahrens s = "MTU check failed, use lower MTU or -f option";
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm break;
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm case DLADM_STATUS_BADPROP:
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm s = "invalid property";
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_MINMAXBW:
e7437265dc2a4920c197ed4337665539d358b22cahrens s = "minimum value for maxbw is 1200K";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
f94275ce205810a201404c5f35f4cc96057022b1Adam Leventhal case DLADM_STATUS_NO_HWRINGS:
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens s = "request hw rings failed";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_PERMONLY:
e7437265dc2a4920c197ed4337665539d358b22cahrens s = "change must be persistent";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_OPTMISSING:
990b4856d0eaada6f8140335733a1b1771ed2746lling s = "optional software not installed";
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case DLADM_STATUS_IPTUNTYPE:
a9799022bd90b13722204e80112efaa5bf573099ck s = "invalid IP tunnel type";
a9799022bd90b13722204e80112efaa5bf573099ck break;
a9799022bd90b13722204e80112efaa5bf573099ck case DLADM_STATUS_IPTUNTYPEREQD:
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan s = "IP tunnel type required";
088f389458728c464569a5506b58070254fa4f7dahrens break;
088f389458728c464569a5506b58070254fa4f7dahrens case DLADM_STATUS_BADIPTUNLADDR:
088f389458728c464569a5506b58070254fa4f7dahrens s = "invalid local IP tunnel address";
bb0ade0978a02d3fe0b0165cd4725fdcb593fbfbahrens break;
74e7dc986c89efca1f2e4451c7a572e05e4a6e4fMatthew Ahrens case DLADM_STATUS_BADIPTUNRADDR:
d0f3f37e7f24f68fdbd85386c60e576883622762Mark Shellenbaum s = "invalid remote IP tunnel address";
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens break;
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor case DLADM_STATUS_ADDRINUSE:
f94275ce205810a201404c5f35f4cc96057022b1Adam Leventhal s = "address already in use";
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby break;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson case DLADM_STATUS_POOLCPU:
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick s = "pool and cpus property are mutually exclusive";
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick break;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson case DLADM_STATUS_INVALID_PORT_INSTANCE:
6e1f5caa9321646aa4212d48e32a0d241866d85dNeil Perrin s = "invalid IB phys link";
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum break;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case DLADM_STATUS_PORT_IS_DOWN:
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens s = "port is down";
cde58dbc6a23d4d38db7c8866312be83221c765fMatthew Ahrens break;
6e0cbcaa0c6f2bc34634a4cc17b099f9ecef03d1Matthew Ahrens case DLADM_STATUS_PARTITION_EXISTS:
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante s = "partition already exists";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_PKEY_NOT_PRESENT:
e7437265dc2a4920c197ed4337665539d358b22cahrens s = "PKEY is not present on the port";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_INVALID_PKEY:
e7437265dc2a4920c197ed4337665539d358b22cahrens s = "invalid PKEY";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor case DLADM_STATUS_NO_IB_HW_RESOURCE:
e7437265dc2a4920c197ed4337665539d358b22cahrens s = "IB internal resource not available";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_INVALID_PKEY_TBL_SIZE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw s = "invalid PKEY table size";
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens break;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum case DLADM_STATUS_PORT_NOPROTO:
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum s = "local or remote port requires transport";
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum break;
e7437265dc2a4920c197ed4337665539d358b22cahrens case DLADM_STATUS_INVALID_MTU:
e7437265dc2a4920c197ed4337665539d358b22cahrens s = "MTU check failed, MTU outside of device's supported range";
e7437265dc2a4920c197ed4337665539d358b22cahrens break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
de8267e0f723ed2c38ea9def92d465f69a300f56timh s = "<unknown error>";
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum (void) snprintf(buf, DLADM_STRSIZE, "%s", dgettext(TEXT_DOMAIN, s));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return (buf);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley}
c8ee1847e300c992c76cf25d6c165e6ccf64a113Victor Latushkin
c8ee1847e300c992c76cf25d6c165e6ccf64a113Victor Latushkin/*
c8ee1847e300c992c76cf25d6c165e6ccf64a113Victor Latushkin * Convert a unix errno to a dladm_status_t.
c8ee1847e300c992c76cf25d6c165e6ccf64a113Victor Latushkin * We only convert errnos that are likely to be encountered. All others
c8ee1847e300c992c76cf25d6c165e6ccf64a113Victor Latushkin * are mapped to DLADM_STATUS_FAILED.
c8ee1847e300c992c76cf25d6c165e6ccf64a113Victor Latushkin */
c8ee1847e300c992c76cf25d6c165e6ccf64a113Victor Latushkindladm_status_t
468c413a79615e77179e8d98f22a7e513a8135bdTim Haleydladm_errno2status(int err)
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley{
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley switch (err) {
c8ee1847e300c992c76cf25d6c165e6ccf64a113Victor Latushkin case 0:
c8ee1847e300c992c76cf25d6c165e6ccf64a113Victor Latushkin return (DLADM_STATUS_OK);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley case EINVAL:
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return (DLADM_STATUS_BADARG);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley case EEXIST:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_EXIST);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ENOENT:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_NOTFOUND);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ENOSPC:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_TOOSMALL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ENOMEM:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_NOMEM);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ENOTSUP:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_NOTSUP);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ENETDOWN:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_NONOTIF);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACCES:
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EPERM:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_DENIED);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EIO:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_IOERR);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EBUSY:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_LINKBUSY);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EAGAIN:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_TRYAGAIN);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ENOTEMPTY:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_FLOW_EXISTS);
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EOPNOTSUPP:
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling return (DLADM_STATUS_FLOW_INCOMPATIBLE);
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case EALREADY:
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock return (DLADM_STATUS_FLOW_IDENTICAL);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case EADDRINUSE:
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (DLADM_STATUS_ADDRINUSE);
99653d4ee642c6528e88224f12409a5f23060994eschrock default:
99653d4ee642c6528e88224f12409a5f23060994eschrock return (DLADM_STATUS_FAILED);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
95173954d2b811ceb583a9012c3b16e1d0dd6438ek}
95173954d2b811ceb583a9012c3b16e1d0dd6438ek
11027bc778dc4f44eabf0c8bc54260ea890b0a15Tim Haleyboolean_t
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockdladm_str2interval(char *oarg, uint32_t *interval)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock{
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin int val;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan char *endp = NULL;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson errno = 0;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson val = strtol(oarg, &endp, 10);
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson if (errno != 0 || val <= 0 || *endp != '\0')
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson return (B_FALSE);
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante *interval = val;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (B_TRUE);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante}
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musantedladm_status_t
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwickdladm_str2bw(char *oarg, uint64_t *bw)
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw{
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw char *endp = NULL;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson int64_t n;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson int mult = 1;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock n = strtoull(oarg, &endp, 10);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if ((errno != 0) || (strlen(endp) > 1))
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (DLADM_STATUS_BADARG);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (n < 0)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (DLADM_STATUS_BADVAL);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
6809eb4e2a4a94bcc76229c7b5108b96134537b6Eric Schrock switch (*endp) {
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock case 'k':
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'K':
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley mult = 1000;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley break;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley case 'm':
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley case 'M':
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley case '\0':
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley mult = 1000000;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley break;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley case 'g':
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley case 'G':
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley mult = 1000000000;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley break;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley case '%':
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * percentages not supported for now,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * see RFE 6540675
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_NOTSUP);
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_BADVAL);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson }
99653d4ee642c6528e88224f12409a5f23060994eschrock
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin *bw = n * mult;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check for overflow */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*bw / mult != n)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_BADARG);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_OK);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Convert bandwidth in bps to a string in Mbps. For values greater
fa9e4066f08beec538e775443c5be79dd423fcabahrens * than 1Mbps or 1000000, print a whole Mbps value. For values that
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock * have fractional Mbps in whole Kbps, print the bandwidth in a manner
fa9e4066f08beec538e775443c5be79dd423fcabahrens * similar to a floating point format.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * bps string
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 0 0
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 100 0
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 2000 0.002
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 431000 0.431
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 1000000 1
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 1030000 1.030
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * 100000000 100
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockconst char *
fa9e4066f08beec538e775443c5be79dd423fcabahrensdladm_bw2str(int64_t bw, char *buf)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int kbps, mbps;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock kbps = (bw%1000000)/1000;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock mbps = bw/1000000;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (kbps != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mbps == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(buf, DLADM_STRSIZE, "0.%03u", kbps);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(buf, DLADM_STRSIZE, "%5u.%03u", mbps,
fa9e4066f08beec538e775443c5be79dd423fcabahrens kbps);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(buf, DLADM_STRSIZE, "%5u", mbps);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (buf);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock}
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock#define LOCK_DB_PERMS S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
32b87932f3ef0887d873b7f6d2d1943799b2afc0ekstatic int
b87f3af36bb994656da117319f5129ddfd05ed21perrini_dladm_lock_db(const char *lock_file, short type)
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock{
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante int lock_fd;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante struct flock lock;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((lock_fd = open(lock_file, O_RDWR | O_CREAT | O_TRUNC,
fa9e4066f08beec538e775443c5be79dd423fcabahrens LOCK_DB_PERMS)) < 0)
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock return (-1);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan lock.l_type = type;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan lock.l_whence = SEEK_SET;
fa9e4066f08beec538e775443c5be79dd423fcabahrens lock.l_start = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens lock.l_len = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (fcntl(lock_fd, F_SETLKW, &lock) < 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens int err = errno;
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan (void) close(lock_fd);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) unlink(lock_file);
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock errno = err;
46a2abf27af40eda17a3f97e79eda1aef4e3c3c8eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (lock_fd);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Lingi_dladm_unlock_db(const char *lock_file, int fd)
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling{
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling struct flock lock;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling if (fd < 0)
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens lock.l_type = F_UNLCK;
fa9e4066f08beec538e775443c5be79dd423fcabahrens lock.l_whence = SEEK_SET;
fa9e4066f08beec538e775443c5be79dd423fcabahrens lock.l_start = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens lock.l_len = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fcntl(fd, F_SETLKW, &lock);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) close(fd);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) unlink(lock_file);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a link class, returns its class string.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Lingconst char *
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Lingdladm_class2str(datalink_class_t class, char *buf)
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling{
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling const char *s;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling switch (class) {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case DATALINK_CLASS_PHYS:
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling s = "phys";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling break;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case DATALINK_CLASS_VLAN:
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling s = "vlan";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling break;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case DATALINK_CLASS_AGGR:
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling s = "aggr";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling break;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case DATALINK_CLASS_VNIC:
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling s = "vnic";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling break;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case DATALINK_CLASS_ETHERSTUB:
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling s = "etherstub";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling break;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case DATALINK_CLASS_IPTUN:
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling s = "iptun";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling break;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case DATALINK_CLASS_SIMNET:
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling s = "simnet";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling break;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case DATALINK_CLASS_BRIDGE:
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling s = "bridge";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case DATALINK_CLASS_PART:
fa9e4066f08beec538e775443c5be79dd423fcabahrens s = "part";
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens s = "unknown";
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(buf, DLADM_STRSIZE, "%s", s);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (buf);
99653d4ee642c6528e88224f12409a5f23060994eschrock}
2a79c5fee1dab68e30266ba4356cf60b871aabcflling
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a physical link media type, returns its media type string.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst char *
fa9e4066f08beec538e775443c5be79dd423fcabahrensdladm_media2str(uint32_t media, char *buf)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling const char *s = "--";
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling media_type_t *mt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int idx;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson for (idx = 0; idx < MEDIATYPECOUNT; idx++) {
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson mt = media_type_table + idx;
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson if (mt->media_type == media) {
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson s = mt->media_type_str;
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson break;
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson }
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson }
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson (void) snprintf(buf, DLADM_STRSIZE, "%s", s);
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson return (buf);
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson}
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson/*
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson * Given a physical link media type string, returns its media type constant.
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson */
9eb19f4d61679ca0382def038665019234458eddGeorge Wilsonuint32_t
9eb19f4d61679ca0382def038665019234458eddGeorge Wilsondladm_str2media(const char *buf)
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson{
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson media_type_t *mt;
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson int idx;
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson for (idx = 0; idx < MEDIATYPECOUNT; idx++) {
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson mt = media_type_table + idx;
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson if (strcasecmp(buf, mt->media_type_str) == 0)
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson return (mt->media_type);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DL_OTHER);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
681d9761e8516a7dc5ab6589e2dfe717777e1123Eric Taylor
681d9761e8516a7dc5ab6589e2dfe717777e1123Eric Taylordladm_status_t
681d9761e8516a7dc5ab6589e2dfe717777e1123Eric Taylori_dladm_rw_db(dladm_handle_t handle, const char *db_file, mode_t db_perms,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson dladm_status_t (*process_db)(dladm_handle_t, void *, FILE *, FILE *),
681d9761e8516a7dc5ab6589e2dfe717777e1123Eric Taylor void *arg, boolean_t writeop)
681d9761e8516a7dc5ab6589e2dfe717777e1123Eric Taylor{
681d9761e8516a7dc5ab6589e2dfe717777e1123Eric Taylor dladm_status_t status = DLADM_STATUS_OK;
fa9e4066f08beec538e775443c5be79dd423fcabahrens FILE *fp, *nfp = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char lock[MAXPATHLEN];
c144956179190829a882ff695f7771ba19f65becEric Taylor char file[MAXPATHLEN];
fa9e4066f08beec538e775443c5be79dd423fcabahrens char newfile[MAXPATHLEN];
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *db_basename;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int nfd, lock_fd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we are called from a boot script such as net-physical,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * it's quite likely that the root fs is still not writable.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * For this case, it's ok for the lock creation to fail since
fa9e4066f08beec538e775443c5be79dd423fcabahrens * no one else could be accessing our configuration file.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens db_basename = strrchr(db_file, '/');
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (db_basename == NULL || db_basename[1] == '\0')
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dladm_errno2status(EINVAL));
fa9e4066f08beec538e775443c5be79dd423fcabahrens db_basename++;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling (void) snprintf(lock, MAXPATHLEN, "/tmp/%s.lock", db_basename);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((lock_fd = i_dladm_lock_db
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (lock, (writeop ? F_WRLCK : F_RDLCK))) < 0 && errno != EROFS)
06eeb2ad640ce72d394ac521094bed7681044408ek return (dladm_errno2status(errno));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(file, MAXPATHLEN, "%s/%s", dladm_rootdir, db_file);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if ((fp = fopen(file, (writeop ? "r+" : "r"))) == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens int err = errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock i_dladm_unlock_db(lock, lock_fd);
6809eb4e2a4a94bcc76229c7b5108b96134537b6Eric Schrock if (err == ENOENT)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_DBNOTFOUND);
de8267e0f723ed2c38ea9def92d465f69a300f56timh
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dladm_errno2status(err));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (writeop) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(newfile, MAXPATHLEN, "%s/%s.new",
fa9e4066f08beec538e775443c5be79dd423fcabahrens dladm_rootdir, db_file);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((nfd = open(newfile, O_WRONLY | O_CREAT | O_TRUNC,
3cb34c601f3ef3016f638574f5982e80c3735c71ahrens db_perms)) < 0) {
3cb34c601f3ef3016f638574f5982e80c3735c71ahrens (void) fclose(fp);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock i_dladm_unlock_db(lock, lock_fd);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (dladm_errno2status(errno));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if ((nfp = fdopen(nfd, "w")) == NULL) {
1d452cf5123cb6ac0a013a4dbd4dcceeb0da314dahrens (void) close(nfd);
1d452cf5123cb6ac0a013a4dbd4dcceeb0da314dahrens (void) fclose(fp);
55434c770c89aa1b84474f2559a106803511aba0ek (void) unlink(newfile);
55434c770c89aa1b84474f2559a106803511aba0ek i_dladm_unlock_db(lock, lock_fd);
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (dladm_errno2status(errno));
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks status = (*process_db)(handle, arg, fp, nfp);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (!writeop || status != DLADM_STATUS_OK)
e45ce728996d8e573eecb27f555fb86aaff0cafdahrens goto done;
743a77ed89085d3c232c4a2f65ab4e19576839e2Alan Wright
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens /* Set permissions on file to db_perms */
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if (fchmod(nfd, db_perms) < 0) {
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens status = dladm_errno2status(errno);
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby goto done;
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby }
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /*
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * Configuration files need to be owned by the 'dladm' user and
99d5e173470cf967aa87653364ed614299e7b511Tim Haley * 'netadm' group.
99d5e173470cf967aa87653364ed614299e7b511Tim Haley */
99d5e173470cf967aa87653364ed614299e7b511Tim Haley if (fchown(nfd, UID_DLADM, GID_NETADM) < 0) {
99d5e173470cf967aa87653364ed614299e7b511Tim Haley status = dladm_errno2status(errno);
99d5e173470cf967aa87653364ed614299e7b511Tim Haley goto done;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (fflush(nfp) == EOF) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock status = dladm_errno2status(errno);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock goto done;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson (void) fclose(fp);
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson (void) fclose(nfp);
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (rename(newfile, file) < 0) {
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson (void) unlink(newfile);
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson i_dladm_unlock_db(lock, lock_fd);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (dladm_errno2status(errno));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock i_dladm_unlock_db(lock, lock_fd);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (DLADM_STATUS_OK);
55434c770c89aa1b84474f2559a106803511aba0ek
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrockdone:
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if (nfp != NULL) {
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock (void) fclose(nfp);
06eeb2ad640ce72d394ac521094bed7681044408ek if (status != DLADM_STATUS_OK)
06eeb2ad640ce72d394ac521094bed7681044408ek (void) unlink(newfile);
06eeb2ad640ce72d394ac521094bed7681044408ek }
06eeb2ad640ce72d394ac521094bed7681044408ek (void) fclose(fp);
06eeb2ad640ce72d394ac521094bed7681044408ek i_dladm_unlock_db(lock, lock_fd);
06eeb2ad640ce72d394ac521094bed7681044408ek return (status);
06eeb2ad640ce72d394ac521094bed7681044408ek}
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ekdladm_status_t
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarksdladm_set_rootdir(const char *rootdir)
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks{
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks DIR *dp;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (rootdir == NULL || *rootdir != '/' ||
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (dp = opendir(rootdir)) == NULL)
06eeb2ad640ce72d394ac521094bed7681044408ek return (DLADM_STATUS_BADARG);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) strncpy(dladm_rootdir, rootdir, MAXPATHLEN);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) closedir(dp);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (DLADM_STATUS_OK);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock}
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilsonboolean_t
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockdladm_valid_linkname(const char *link)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock{
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson size_t len = strlen(link);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson const char *cp;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (len >= MAXLINKNAMELEN)
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson return (B_FALSE);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson /*
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson * The link name cannot start with a digit and must end with a digit.
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson */
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if ((isdigit(link[0]) != 0) || (isdigit(link[len - 1]) == 0))
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (B_FALSE);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock /*
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * The legal characters in a link name are:
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * alphanumeric (a-z, A-Z, 0-9), underscore ('_'), and '.'.
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock */
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock for (cp = link; *cp != '\0'; cp++) {
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if ((isalnum(*cp) == 0) && (*cp != '_') && (*cp != '.'))
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (B_FALSE);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock }
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (B_TRUE);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock}
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock/*
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * Convert priority string to a value.
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock */
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockdladm_status_t
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockdladm_str2pri(char *token, mac_priority_level_t *pri)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock{
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (strlen(token) == strlen("low") &&
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock strncasecmp(token, "low", strlen("low")) == 0) {
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock *pri = MPL_LOW;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock } else if (strlen(token) == strlen("medium") &&
088f389458728c464569a5506b58070254fa4f7dahrens strncasecmp(token, "medium", strlen("medium")) == 0) {
088f389458728c464569a5506b58070254fa4f7dahrens *pri = MPL_MEDIUM;
088f389458728c464569a5506b58070254fa4f7dahrens } else if (strlen(token) == strlen("high") &&
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson strncasecmp(token, "high", strlen("high")) == 0) {
088f389458728c464569a5506b58070254fa4f7dahrens *pri = MPL_HIGH;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks } else {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks return (DLADM_STATUS_BADVAL);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks return (DLADM_STATUS_OK);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks}
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks/*
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks * Convert priority value to a string.
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks */
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarksconst char *
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarksdladm_pri2str(mac_priority_level_t pri, char *buf)
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks{
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks const char *s;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks switch (pri) {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling case MPL_LOW:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "low";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case MPL_MEDIUM:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "medium";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case MPL_HIGH:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "high";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks default:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks s = "--";
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) snprintf(buf, DLADM_STRSIZE, "%s", dgettext(TEXT_DOMAIN, s));
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks return (buf);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks}
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks/*
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks * Convert protect string to a value.
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks */
e7437265dc2a4920c197ed4337665539d358b22cahrensdladm_status_t
a9799022bd90b13722204e80112efaa5bf573099ckdladm_str2protect(char *token, uint32_t *ptype)
a9799022bd90b13722204e80112efaa5bf573099ck{
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling link_protect_t *lp;
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby int i;
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante for (i = 0; i < LPTYPES; i++) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks lp = &link_protect_types[i];
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (strcmp(token, lp->lp_name) == 0) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks *ptype = lp->lp_type;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_OK);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (DLADM_STATUS_BADVAL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
/*
* Convert protect value to a string.
*/
const char *
dladm_protect2str(uint32_t ptype, char *buf)
{
const char *s = "--";
link_protect_t *lp;
int i;
for (i = 0; i < LPTYPES; i++) {
lp = &link_protect_types[i];
if (lp->lp_type == ptype) {
s = lp->lp_name;
break;
}
}
(void) snprintf(buf, DLADM_STRSIZE, "%s", dgettext(TEXT_DOMAIN, s));
return (buf);
}
/*
* Convert an IPv4 address to/from a string.
*/
const char *
dladm_ipv4addr2str(void *addr, char *buf)
{
if (inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN) == NULL)
buf[0] = '\0';
return (buf);
}
dladm_status_t
dladm_str2ipv4addr(char *token, void *addr)
{
return (inet_pton(AF_INET, token, addr) == 1 ?
DLADM_STATUS_OK : DLADM_STATUS_INVALID_IP);
}
const char *
dladm_ipv6addr2str(void *addr, char *buf)
{
if (inet_ntop(AF_INET6, addr, buf, INET6_ADDRSTRLEN) == NULL)
buf[0] = '\0';
return (buf);
}
dladm_status_t
dladm_str2ipv6addr(char *token, void *addr)
{
return (inet_pton(AF_INET6, token, addr) == 1 ?
DLADM_STATUS_OK : DLADM_STATUS_INVALID_IP);
}
/*
* Find the set bits in a mask.
* This is used for expanding a bitmask into individual sub-masks
* which can be used for further processing.
*/
void
dladm_find_setbits32(uint32_t mask, uint32_t *list, uint32_t *cnt)
{
int i, c = 0;
for (i = 0; i < 32; i++) {
if (((1 << i) & mask) != 0)
list[c++] = 1 << i;
}
*cnt = c;
}
void
dladm_free_args(dladm_arg_list_t *list)
{
if (list != NULL) {
free(list->al_buf);
free(list);
}
}
dladm_status_t
dladm_parse_args(char *str, dladm_arg_list_t **listp, boolean_t novalues)
{
dladm_arg_list_t *list;
dladm_arg_info_t *aip;
char *buf, *curr;
int len, i;
if (str == NULL)
return (DLADM_STATUS_BADVAL);
if (str[0] == '\0')
return (DLADM_STATUS_OK);
list = malloc(sizeof (dladm_arg_list_t));
if (list == NULL)
return (dladm_errno2status(errno));
list->al_count = 0;
list->al_buf = buf = strdup(str);
if (buf == NULL)
return (dladm_errno2status(errno));
curr = buf;
len = strlen(buf);
aip = NULL;
for (i = 0; i < len; i++) {
char c = buf[i];
boolean_t match = (c == '=' || c == ',');
if (!match && i != len - 1)
continue;
if (match) {
buf[i] = '\0';
if (*curr == '\0')
goto fail;
}
if (aip != NULL && c != '=') {
if (aip->ai_count > DLADM_MAX_ARG_VALS)
goto fail;
if (novalues)
goto fail;
aip->ai_val[aip->ai_count] = curr;
aip->ai_count++;
} else {
if (list->al_count > DLADM_MAX_ARG_VALS)
goto fail;
aip = &list->al_info[list->al_count];
aip->ai_name = curr;
aip->ai_count = 0;
list->al_count++;
if (c == ',')
aip = NULL;
}
curr = buf + i + 1;
}
*listp = list;
return (DLADM_STATUS_OK);
fail:
dladm_free_args(list);
return (DLADM_STATUS_FAILED);
}
/*
* mac_propval_range_t functions. Currently implemented for only
* ranges of uint32_t elements, but can be expanded as required.
*/
/*
* Convert an array of strings (which can be ranges or individual
* elements) into a single mac_propval_range_t structure which
* is allocated here but should be freed by the caller.
*/
dladm_status_t
dladm_strs2range(char **prop_val, uint_t val_cnt,
mac_propval_type_t type, mac_propval_range_t **range)
{
int i;
char *endp;
mac_propval_range_t *rangep;
dladm_status_t status = DLADM_STATUS_OK;
switch (type) {
case MAC_PROPVAL_UINT32: {
mac_propval_uint32_range_t *ur;
/* Allocate range structure */
rangep = malloc(sizeof (mac_propval_range_t) +
(val_cnt-1)*(sizeof (mac_propval_uint32_range_t)));
if (rangep == NULL)
return (DLADM_STATUS_NOMEM);
rangep->mpr_count = 0;
ur = &rangep->mpr_range_uint32[0];
for (i = 0; i < val_cnt; i++, ur++) {
errno = 0;
if (strchr(prop_val[i], '-') == NULL) {
/* single element */
ur->mpur_min = ur->mpur_max =
strtol(prop_val[i], &endp, 10);
if ((endp != NULL) && (*endp != '\0')) {
return (DLADM_STATUS_BADRANGE);
}
} else {
/* range of elements */
ur->mpur_min = strtol(prop_val[i], &endp, 10);
if (*endp++ != '-')
return (DLADM_STATUS_BADRANGE);
ur->mpur_max = strtol(endp, &endp, 10);
if (endp != NULL && *endp != '\0' ||
ur->mpur_max < ur->mpur_min)
return (DLADM_STATUS_BADRANGE);
}
rangep->mpr_count++;
}
break;
}
default:
return (DLADM_STATUS_BADVAL);
}
rangep->mpr_type = type;
*range = rangep;
return (status);
}
/*
* Convert a mac_propval_range_t structure into an array of elements.
*/
dladm_status_t
dladm_range2list(mac_propval_range_t *rangep, void *elem, uint_t *nelem)
{
int i, j, k;
dladm_status_t status = DLADM_STATUS_OK;
switch (rangep->mpr_type) {
case MAC_PROPVAL_UINT32: {
mac_propval_uint32_range_t *ur;
uint32_t *elem32 = elem;
k = 0;
ur = &rangep->mpr_range_uint32[0];
for (i = 0; i < rangep->mpr_count; i++, ur++) {
for (j = 0; j <= ur->mpur_max - ur->mpur_min; j++) {
elem32[k++] = ur->mpur_min + j;
if (k > *nelem) {
status = DLADM_STATUS_TOOMANYELEMENTS;
break;
}
}
}
*nelem = k;
break;
}
default:
status = DLADM_STATUS_BADVAL;
break;
}
return (status);
}
/*
* Convert a mac_propval_range_t structure into an array of strings
* of single elements or ranges.
*/
int
dladm_range2strs(mac_propval_range_t *rangep, char **prop_val)
{
int i;
switch (rangep->mpr_type) {
case MAC_PROPVAL_UINT32: {
mac_propval_uint32_range_t *ur;
/* Write ranges and individual elements */
ur = &rangep->mpr_range_uint32[0];
for (i = 0; i < rangep->mpr_count; i++, ur++) {
if (ur->mpur_min == ur->mpur_max) {
/* single element */
(void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX,
"%u", ur->mpur_min);
} else {
/* range of elements */
(void) snprintf(prop_val[i], DLADM_PROP_VAL_MAX,
"%u-%u", ur->mpur_min, ur->mpur_max);
}
}
return (0);
}
default:
break;
}
return (EINVAL);
}
static int
uint32cmp(const void *a, const void *b)
{
return (*(uint32_t *)a - *(uint32_t *)b);
}
/*
* Sort and convert an array of elements into a single
* mac_propval_range_t structure which is allocated here but
* should be freed by the caller.
*/
dladm_status_t
dladm_list2range(void *elem, uint_t nelem, mac_propval_type_t type,
mac_propval_range_t **range)
{
int i;
uint_t nr = 0;
mac_propval_range_t *rangep;
dladm_status_t status = DLADM_STATUS_OK;
switch (type) {
case MAC_PROPVAL_UINT32: {
mac_propval_uint32_range_t *ur;
uint32_t *elem32 = elem;
uint32_t *sort32;
/* Allocate range structure */
rangep = malloc(sizeof (mac_propval_range_t) +
(nelem-1)*(sizeof (mac_propval_uint32_range_t)));
if (rangep == NULL)
return (DLADM_STATUS_NOMEM);
/* Allocate array for sorting */
sort32 = malloc(nelem * sizeof (uint32_t));
if (sort32 == NULL) {
free(rangep);
return (DLADM_STATUS_NOMEM);
}
/* Copy and sort list */
for (i = 0; i < nelem; i++)
sort32[i] = elem32[i];
if (nelem > 1)
qsort(sort32, nelem, sizeof (uint32_t), uint32cmp);
/* Convert list to ranges */
ur = &rangep->mpr_range_uint32[0];
ur->mpur_min = ur->mpur_max = sort32[0];
for (i = 1; i < nelem; i++) {
if (sort32[i]-sort32[i-1] == 1) {
/* part of current range */
ur->mpur_max = sort32[i];
} else {
/* start a new range */
nr++; ur++;
ur->mpur_min = ur->mpur_max = sort32[i];
}
}
free(sort32);
break;
}
default:
return (DLADM_STATUS_BADRANGE);
}
rangep->mpr_type = type;
rangep->mpr_count = nr + 1;
*range = rangep;
return (status);
}