diff options
author | yz147064 <none@none> | 2008-01-23 18:09:15 -0800 |
---|---|---|
committer | yz147064 <none@none> | 2008-01-23 18:09:15 -0800 |
commit | d62bc4badc1c1f1549c961cfb8b420e650e1272b (patch) | |
tree | 9f466859e9cfb73da13b64261432aba4683f19ad /usr/src/lib/libdladm/common/libdlvnic.c | |
parent | d38257c4392a9dd690c2f7f2383236c1fc80e509 (diff) | |
download | illumos-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.c | 364 |
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); } |