summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdladm/common/libdlvnic.c
diff options
context:
space:
mode:
authoryz147064 <none@none>2008-01-23 18:09:15 -0800
committeryz147064 <none@none>2008-01-23 18:09:15 -0800
commitd62bc4badc1c1f1549c961cfb8b420e650e1272b (patch)
tree9f466859e9cfb73da13b64261432aba4683f19ad /usr/src/lib/libdladm/common/libdlvnic.c
parentd38257c4392a9dd690c2f7f2383236c1fc80e509 (diff)
downloadillumos-joyent-d62bc4badc1c1f1549c961cfb8b420e650e1272b.tar.gz
PSARC/2006/499 Clearview Nemo unification and vanity naming
PSARC/2007/527 Addendum for Clearview Vanity Naming and Nemo Unification PSARC/2008/002 Clearview UV Updates 6310766 vlan statistics get reset at unplumb time 6320515 dladm commands with "-R" option should not take effect immediately 6433732 Simplify the GLDv3 control path by making its processing asynchronous 6445912 dladm show-link fails to show a specific link in the debug version 6452413 dladm show-link doesn't show VLAN links for GLDv2 drivers 6504433 libwladm's use of wladm_wlresult2status() needs an overhaul 6504507 dladm set-linkprop failure message is unclear 6534289 DR should work with aggregations 6535719 dladm_aggr_port_attr_db_t`lp_devname should be MAXNAMELEN, not MAXNAMELEN + 1 6539634 GLDv3 should DL_ERROR_ACK a DL_UDQOS_REQ with DL_OUTSTATE when the stream is DL_UNATTACHED 6540246 libdladm should not guess zoneid from DLDIOCZIDGET ioctl errno 6544195 dladm show-dev assumes GLDv3 stats.. incompatible with GLDv2 6563295 dladm show-linkprop -P does not work properly for unavailable links 6577618 integrate network vanity naming and nemo unification 6600446 links assigned to a local zone are still aggregatable by global zone 6607572 "boot net - install" can trigger assertion failure in dld_str_attach() 6613956 "svccfg import -" does not work as bfu expects 6637596 invalid assertion in ip_soft_ring_assignment() 6642350 kernel DLPI processing routines are long overdue 6643338 GLDv3 PPA hack VLAN ID checks don't always work 6647203 bfu: smf_delete_manifest() does not work for non-global zones 6649885 DL_IB GLDv3 mactype plugin must fill in its mtr_nativetype 6650395 libuuid should be lint-clean and linted nightly --HG-- rename : usr/src/cmd/dladm/aggregation.conf => deleted_files/usr/src/cmd/dladm/aggregation.conf rename : usr/src/cmd/dladm/linkprop.conf => deleted_files/usr/src/cmd/dladm/linkprop.conf rename : usr/src/lib/libinetcfg/common/inetcfg_nic.c => deleted_files/usr/src/lib/libinetcfg/common/inetcfg_nic.c rename : usr/src/lib/libinetcfg/common/inetcfg_nic.h => deleted_files/usr/src/lib/libinetcfg/common/inetcfg_nic.h
Diffstat (limited to 'usr/src/lib/libdladm/common/libdlvnic.c')
-rw-r--r--usr/src/lib/libdladm/common/libdlvnic.c364
1 files changed, 86 insertions, 278 deletions
diff --git a/usr/src/lib/libdladm/common/libdlvnic.c b/usr/src/lib/libdladm/common/libdlvnic.c
index da9d57cd1b..272763b61d 100644
--- a/usr/src/lib/libdladm/common/libdlvnic.c
+++ b/usr/src/lib/libdladm/common/libdlvnic.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,6 +39,7 @@
#include <net/if_types.h>
#include <net/if_dl.h>
#include <libdladm_impl.h>
+#include <libdllink.h>
#include <libdlvnic.h>
/*
@@ -47,51 +48,19 @@
#define VNIC_DEV "/devices/pseudo/vnic@0:" VNIC_CTL_NODE_NAME
-/*
- * Because by default the id is used as the DLPI device PPA and default
- * VLAN PPA's are calculated as ((1000 * vid) + PPA), the largest id
- * can't be > 999. We reserve the last 100 VNIC ids for automatic
- * VNIC id assignment.
- */
-#define DLADM_VNIC_MIN_VNIC_ID 1 /* total range */
-#define DLADM_VNIC_MAX_VNIC_ID 999
-#define DLADM_VNIC_MIN_VNIC_SPEC_ID 1 /* specified by user */
-#define DLADM_VNIC_MAX_VNIC_SPEC_ID 899
-#define DLADM_VNIC_MIN_VNIC_AUTO_ID 900 /* picked automatically */
-#define DLADM_VNIC_MAX_VNIC_AUTO_ID 999
-
-#define DLADM_VNIC_NUM_VNIC_AUTO_ID (DLADM_VNIC_MAX_VNIC_AUTO_ID - \
- DLADM_VNIC_MIN_VNIC_AUTO_ID + 1)
-
/* Limits on buffer size for VNIC_IOC_INFO request */
#define MIN_INFO_SIZE (4*1024)
#define MAX_INFO_SIZE (128*1024)
/* configuration database entry */
typedef struct dladm_vnic_attr_db {
- uint_t vt_vnic_id;
- char vt_dev_name[MAXNAMELEN];
+ datalink_id_t vt_vnic_id;
+ datalink_id_t vt_link_id;
vnic_mac_addr_type_t vt_mac_addr_type;
uint_t vt_mac_len;
uchar_t vt_mac_addr[MAXMACADDRLEN];
} dladm_vnic_attr_db_t;
-typedef struct dladm_vnic_up {
- uint_t vu_vnic_id;
- boolean_t vu_found;
- int vu_fd;
-} dladm_vnic_up_t;
-
-typedef struct dladm_vnic_down {
- uint32_t vd_vnic_id;
- boolean_t vd_found;
-} dladm_vnic_down_t;
-
-typedef struct dladm_vnic_modify {
- uint32_t vm_vnic_id;
- boolean_t vm_found;
-} dladm_vnic_modify_t;
-
typedef struct dladm_vnic_modify_attr {
vnic_mac_addr_type_t vm_mac_addr_type;
int vm_mac_len;
@@ -108,7 +77,7 @@ i_dladm_vnic_create_sys(int fd, dladm_vnic_attr_db_t *attr)
vnic_ioc_create_t ioc;
ioc.vc_vnic_id = attr->vt_vnic_id;
- bcopy(attr->vt_dev_name, ioc.vc_dev_name, MAXNAMELEN);
+ ioc.vc_link_id = attr->vt_link_id;
ioc.vc_mac_addr_type = attr->vt_mac_addr_type;
ioc.vc_mac_len = attr->vt_mac_len;
bcopy(attr->vt_mac_addr, ioc.vc_mac_addr, attr->vt_mac_len);
@@ -122,31 +91,10 @@ i_dladm_vnic_create_sys(int fd, dladm_vnic_attr_db_t *attr)
}
/*
- * Invoked to bring up a VNIC.
- */
-static dladm_status_t
-i_dladm_vnic_up(void *arg, dladm_vnic_attr_db_t *attr)
-{
- dladm_vnic_up_t *up = (dladm_vnic_up_t *)arg;
- dladm_status_t status;
-
- if (up->vu_vnic_id != 0 && up->vu_vnic_id != attr->vt_vnic_id)
- return (DLADM_STATUS_OK);
-
- up->vu_found = B_TRUE;
-
- status = i_dladm_vnic_create_sys(up->vu_fd, attr);
- if ((status != DLADM_STATUS_OK) && (up->vu_vnic_id != 0))
- return (status);
-
- return (DLADM_STATUS_OK);
-}
-
-/*
* Send a modify command to the VNIC driver.
*/
static dladm_status_t
-i_dladm_vnic_modify_sys(uint_t vnic_id, uint32_t modify_mask,
+i_dladm_vnic_modify_sys(datalink_id_t vnic_id, uint32_t modify_mask,
dladm_vnic_modify_attr_t *attr)
{
int rc;
@@ -177,75 +125,49 @@ i_dladm_vnic_modify_sys(uint_t vnic_id, uint32_t modify_mask,
}
/*
- * Walk through the vnics defined on the system and for each vnic <vnic>,
- * invoke <fn>(<arg>, <vnic>);
+ * Get the configuration information of the given VNIC.
*/
dladm_status_t
-dladm_vnic_walk_sys(dladm_status_t (*fn)(void *, dladm_vnic_attr_sys_t *),
- void *arg)
+dladm_vnic_info(datalink_id_t vnic_id, dladm_vnic_attr_sys_t *attrp,
+ uint32_t flags)
{
vnic_ioc_info_t *ioc;
vnic_ioc_info_vnic_t *vnic;
- dladm_vnic_attr_sys_t attr;
- int rc, i, bufsize, fd;
- char *where;
+ int rc, bufsize, fd;
dladm_status_t status = DLADM_STATUS_OK;
+ /* for now, only temporary creations are supported */
+ if (flags & DLADM_OPT_PERSIST)
+ return (dladm_errno2status(ENOTSUP));
+
if ((fd = open(VNIC_DEV, O_RDWR)) == -1)
return (dladm_errno2status(errno));
- bufsize = MIN_INFO_SIZE;
+ bufsize = sizeof (vnic_ioc_info_t) + sizeof (vnic_ioc_info_vnic_t);
ioc = (vnic_ioc_info_t *)calloc(1, bufsize);
if (ioc == NULL) {
(void) close(fd);
return (dladm_errno2status(ENOMEM));
}
-tryagain:
-
+ ioc->vi_vnic_id = vnic_id;
rc = i_dladm_ioctl(fd, VNIC_IOC_INFO, ioc, bufsize);
-
if (rc != 0) {
- if (errno == ENOSPC) {
- bufsize *= 2;
- if (bufsize <= MAX_INFO_SIZE) {
- ioc = (vnic_ioc_info_t *)realloc(ioc, bufsize);
- if (ioc != NULL) {
- bzero(ioc, bufsize);
- goto tryagain;
- }
- }
- }
status = dladm_errno2status(errno);
goto bail;
}
- /*
- * Go through each vnic returned by the vnic driver
- */
- where = (char *)(ioc + 1);
-
- for (i = 0; i < ioc->vi_nvnics; i++) {
- /* LINTED E_BAD_PTR_CAST_ALIGN */
- vnic = (vnic_ioc_info_vnic_t *)where;
-
- attr.va_vnic_id = vnic->vn_vnic_id;
- bcopy(vnic->vn_dev_name, attr.va_dev_name,
- MAXNAMELEN);
- attr.va_mac_addr_type = vnic->vn_mac_addr_type;
- bcopy(vnic->vn_mac_addr, attr.va_mac_addr, ETHERADDRL);
- attr.va_mac_len = vnic->vn_mac_len;
- where = (char *)(vnic + 1);
-
- status = fn(arg, &attr);
- if (status != DLADM_STATUS_OK)
- goto bail;
- }
+ vnic = (vnic_ioc_info_vnic_t *)(ioc + 1);
+
+ attrp->va_vnic_id = vnic->vn_vnic_id;
+ attrp->va_link_id = vnic->vn_link_id;
+ attrp->va_mac_addr_type = vnic->vn_mac_addr_type;
+ bcopy(vnic->vn_mac_addr, attrp->va_mac_addr, ETHERADDRL);
+ attrp->va_mac_len = vnic->vn_mac_len;
bail:
free(ioc);
(void) close(fd);
-
return (status);
}
@@ -269,34 +191,6 @@ i_dladm_vnic_delete_sys(int fd, dladm_vnic_attr_sys_t *attr)
}
/*
- * Invoked to bring down a VNIC.
- */
-static dladm_status_t
-i_dladm_vnic_down(void *arg, dladm_vnic_attr_sys_t *attr)
-{
- dladm_vnic_down_t *down = (dladm_vnic_down_t *)arg;
- int fd;
- dladm_status_t status;
-
- if (down->vd_vnic_id != 0 && down->vd_vnic_id != attr->va_vnic_id)
- return (DLADM_STATUS_OK);
-
- down->vd_found = B_TRUE;
-
- if ((fd = open(VNIC_DEV, O_RDWR)) < 0)
- return (dladm_errno2status(errno));
-
- status = i_dladm_vnic_delete_sys(fd, attr);
- if ((status != DLADM_STATUS_OK) && (down->vd_vnic_id != 0)) {
- (void) close(fd);
- return (status);
- }
-
- (void) close(fd);
- return (DLADM_STATUS_OK);
-}
-
-/*
* Convert between MAC address types and their string representations.
*/
@@ -311,9 +205,12 @@ static dladm_vnic_addr_type_t addr_types[] = {
#define NADDR_TYPES (sizeof (addr_types) / sizeof (dladm_vnic_addr_type_t))
-/* returns B_TRUE if a matching type was found, B_FALSE otherwise */
-boolean_t
-dladm_vnic_mac_addr_str_to_type(const char *str, vnic_mac_addr_type_t *val)
+/*
+ * Return DLADM_STATUS_OK if a matching type was found,
+ * DLADM_STATUS_BADARG otherwise
+ */
+dladm_status_t
+dladm_vnic_str2macaddrtype(const char *str, vnic_mac_addr_type_t *val)
{
int i;
dladm_vnic_addr_type_t *type;
@@ -322,127 +219,34 @@ dladm_vnic_mac_addr_str_to_type(const char *str, vnic_mac_addr_type_t *val)
type = &addr_types[i];
if (strncmp(str, type->va_str, strlen(type->va_str)) == 0) {
*val = type->va_type;
- return (B_TRUE);
+ return (DLADM_STATUS_OK);
}
}
- return (B_FALSE);
-}
-
-/*
- * Select a VNIC id automatically.
- */
-
-typedef struct dladm_vnic_auto_state_s {
- uint_t as_nslots;
- uint_t *as_slots;
-} dladm_vnic_auto_state_t;
-
-static dladm_status_t
-i_dladm_vnic_create_auto_walker(void *arg, dladm_vnic_attr_sys_t *attr)
-{
- dladm_vnic_auto_state_t *state = arg;
-
- if (attr->va_vnic_id < DLADM_VNIC_MIN_VNIC_AUTO_ID ||
- attr->va_vnic_id > DLADM_VNIC_MAX_VNIC_AUTO_ID)
- return (DLADM_STATUS_OK);
-
- state->as_slots[state->as_nslots++] = attr->va_vnic_id;
-
- return (DLADM_STATUS_OK);
-}
-
-static int
-i_dladm_vnic_compare(const void *p1, const void *p2)
-{
- uint_t i = *((uint_t *)p1);
- uint_t j = *((uint_t *)p2);
-
- if (i > j)
- return (1);
- if (i < j)
- return (-1);
- return (0);
-}
-
-/*ARGSUSED*/
-static dladm_status_t
-i_dladm_vnic_get_auto_id(dladm_vnic_attr_db_t *attr, uint32_t *vnic_id_out)
-{
- dladm_vnic_auto_state_t state;
- uint_t vnic_ids[DLADM_VNIC_NUM_VNIC_AUTO_ID];
- int i;
- uint_t last_id, vnic_id;
- dladm_status_t status;
-
- /*
- * Build a sorted array containing the existing VNIC ids in the range
- * allocated for automatic allocation.
- */
- state.as_nslots = 0;
- state.as_slots = vnic_ids;
-
- status = dladm_vnic_walk_sys(i_dladm_vnic_create_auto_walker, &state);
- if (status != DLADM_STATUS_OK)
- return (status);
-
- qsort(vnic_ids, state.as_nslots, sizeof (uint_t),
- i_dladm_vnic_compare);
-
- /*
- * Find a gap in the sequence of existing VNIC ids.
- */
- last_id = DLADM_VNIC_MIN_VNIC_AUTO_ID - 1;
- vnic_id = 0;
- for (i = 0; i < state.as_nslots; i++) {
- if (vnic_ids[i] > (last_id + 1)) {
- vnic_id = last_id + 1;
- break;
- }
- last_id = vnic_ids[i];
- }
-
- if (vnic_id == 0) {
- /*
- * Did not find a gap between existing entries, see if we
- * can add one.
- */
- if (last_id + 1 > DLADM_VNIC_MAX_VNIC_AUTO_ID)
- return (DLADM_STATUS_AUTOIDNOAVAILABLEID);
-
- /* still have room for one more VNIC */
- vnic_id = last_id + 1;
- }
-
- *vnic_id_out = vnic_id;
-
- return (DLADM_STATUS_OK);
+ return (DLADM_STATUS_BADARG);
}
/*
* Create a new VNIC. Update the configuration file and bring it up.
*/
dladm_status_t
-dladm_vnic_create(uint_t vnic_id, char *dev_name,
+dladm_vnic_create(const char *vnic, datalink_id_t linkid,
vnic_mac_addr_type_t mac_addr_type, uchar_t *mac_addr, int mac_len,
- uint_t *vnic_id_out, uint32_t flags)
+ datalink_id_t *vnic_id_out, uint32_t flags)
{
dladm_vnic_attr_db_t attr;
- int i;
- boolean_t tempop = ((flags & DLADM_VNIC_OPT_TEMP) != 0);
- boolean_t autoid = ((flags & DLADM_VNIC_OPT_AUTOID) != 0);
- dladm_vnic_up_t up;
+ int i, fd;
+ datalink_id_t vnic_id;
+ datalink_class_t class;
+ uint32_t media;
+ char *name = (char *)vnic;
dladm_status_t status;
/*
* Sanity test arguments.
*/
- if (autoid && !tempop)
- return (DLADM_STATUS_AUTOIDNOTEMP);
-
- if (!autoid && ((vnic_id < DLADM_VNIC_MIN_VNIC_SPEC_ID) ||
- (vnic_id > DLADM_VNIC_MAX_VNIC_SPEC_ID)))
- return (DLADM_STATUS_INVALIDID);
+ if (flags & DLADM_OPT_PERSIST)
+ return (dladm_errno2status(ENOTSUP));
if (mac_len > MAXMACADDRLEN)
return (DLADM_STATUS_INVALIDMACADDRLEN);
@@ -454,40 +258,46 @@ dladm_vnic_create(uint_t vnic_id, char *dev_name,
if (i == NADDR_TYPES)
return (DLADM_STATUS_INVALIDMACADDRTYPE);
- /* for now, only temporary creations are supported */
- if (!tempop)
- return (dladm_errno2status(ENOTSUP));
+ if ((status = dladm_datalink_id2info(linkid, NULL, &class, &media,
+ NULL, 0)) != DLADM_STATUS_OK) {
+ return (status);
+ }
-auto_again:
- if (autoid) {
- /*
- * Find an unused VNIC id.
- */
- status = i_dladm_vnic_get_auto_id(&attr, vnic_id_out);
- if (status != DLADM_STATUS_OK)
- return (status);
- vnic_id = *vnic_id_out;
+ if (class == DATALINK_CLASS_VNIC)
+ return (DLADM_STATUS_BADARG);
+
+ if (vnic == NULL) {
+ flags |= DLADM_OPT_PREFIX;
+ name = "vnic";
+ }
+
+ if ((status = dladm_create_datalink_id(name, DATALINK_CLASS_VNIC,
+ media, flags, &vnic_id)) != DLADM_STATUS_OK) {
+ return (status);
}
bzero(&attr, sizeof (attr));
attr.vt_vnic_id = vnic_id;
- (void) strncpy(attr.vt_dev_name, dev_name,
- sizeof (attr.vt_dev_name) - 1);
+ attr.vt_link_id = linkid;
attr.vt_mac_addr_type = mac_addr_type;
attr.vt_mac_len = mac_len;
bcopy(mac_addr, attr.vt_mac_addr, mac_len);
- up.vu_vnic_id = vnic_id;
- up.vu_found = B_FALSE;
- up.vu_fd = open(VNIC_DEV, O_RDWR);
- if (up.vu_fd < 0)
- return (dladm_errno2status(errno));
+ if ((fd = open(VNIC_DEV, O_RDWR)) < 0) {
+ status = dladm_errno2status(errno);
+ goto done;
+ }
- status = i_dladm_vnic_up((void *)&up, &attr);
- (void) close(up.vu_fd);
+ status = i_dladm_vnic_create_sys(fd, &attr);
+ (void) close(fd);
- if ((status == DLADM_STATUS_EXIST) && autoid)
- goto auto_again;
+done:
+ if (status != DLADM_STATUS_OK) {
+ (void) dladm_destroy_datalink_id(vnic_id,
+ flags & ~DLADM_OPT_PREFIX);
+ } else {
+ *vnic_id_out = vnic_id;
+ }
return (status);
}
@@ -496,19 +306,14 @@ auto_again:
* Modify the properties of a VNIC.
*/
dladm_status_t
-dladm_vnic_modify(uint_t vnic_id, uint32_t modify_mask,
+dladm_vnic_modify(datalink_id_t vnic_id, uint32_t modify_mask,
vnic_mac_addr_type_t mac_addr_type, uint_t mac_len, uchar_t *mac_addr,
uint32_t flags)
{
dladm_vnic_modify_attr_t new_attr;
- boolean_t tempop = ((flags & DLADM_VNIC_OPT_TEMP) != 0);
-
- if ((vnic_id < DLADM_VNIC_MIN_VNIC_ID) ||
- (vnic_id > DLADM_VNIC_MAX_VNIC_ID))
- return (DLADM_STATUS_INVALIDID);
/* for now, only temporary creations are supported */
- if (!tempop)
+ if (flags & DLADM_OPT_PERSIST)
return (dladm_errno2status(ENOTSUP));
bzero(&new_attr, sizeof (new_attr));
@@ -523,27 +328,30 @@ dladm_vnic_modify(uint_t vnic_id, uint32_t modify_mask,
return (i_dladm_vnic_modify_sys(vnic_id, modify_mask, &new_attr));
}
-
/*
* Delete a VNIC.
*/
dladm_status_t
-dladm_vnic_delete(uint_t vnic_id, uint32_t flags)
+dladm_vnic_delete(datalink_id_t vnic_id, uint32_t flags)
{
- boolean_t tempop = ((flags & DLADM_VNIC_OPT_TEMP) != 0);
- dladm_vnic_down_t down;
+ dladm_status_t status;
dladm_vnic_attr_sys_t sys_attr;
-
- if ((vnic_id < DLADM_VNIC_MIN_VNIC_ID) ||
- (vnic_id > DLADM_VNIC_MAX_VNIC_ID))
- return (DLADM_STATUS_INVALIDID);
+ int fd;
/* for now, only temporary deletes are supported */
- if (!tempop)
+ if (flags & DLADM_OPT_PERSIST)
return (dladm_errno2status(ENOTSUP));
- down.vd_vnic_id = vnic_id;
- down.vd_found = B_FALSE;
+ if ((fd = open(VNIC_DEV, O_RDWR)) < 0)
+ return (dladm_errno2status(errno));
+
sys_attr.va_vnic_id = vnic_id;
- return (i_dladm_vnic_down((void *)&down, &sys_attr));
+ status = i_dladm_vnic_delete_sys(fd, &sys_attr);
+ (void) close(fd);
+
+ if (status != DLADM_STATUS_OK)
+ return (status);
+
+ (void) dladm_destroy_datalink_id(vnic_id, flags);
+ return (status);
}