summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdladm
diff options
context:
space:
mode:
authorAruna Ramakrishna - Sun Microsystems <Aruna.Ramakrishna@Sun.COM>2008-08-15 14:27:06 -0400
committerAruna Ramakrishna - Sun Microsystems <Aruna.Ramakrishna@Sun.COM>2008-08-15 14:27:06 -0400
commit3bc21d0a9c7b31b1132c254e389a4114c23bcf00 (patch)
treedaf267db046835b41826cd114140ca0503b4bbcc /usr/src/lib/libdladm
parent43afaaa8b73f73af765f4fa90f39a0f86cb8a364 (diff)
downloadillumos-joyent-3bc21d0a9c7b31b1132c254e389a4114c23bcf00.tar.gz
6714745 zone/autopush should be implemented using DLDIOC_*MACPROP ioctls.
Diffstat (limited to 'usr/src/lib/libdladm')
-rw-r--r--usr/src/lib/libdladm/common/libdllink.c105
-rw-r--r--usr/src/lib/libdladm/common/libdllink.h5
-rw-r--r--usr/src/lib/libdladm/common/linkprop.c420
-rw-r--r--usr/src/lib/libdladm/common/mapfile-vers3
4 files changed, 316 insertions, 217 deletions
diff --git a/usr/src/lib/libdladm/common/libdllink.c b/usr/src/lib/libdladm/common/libdllink.c
index 9426327e12..b9179736c2 100644
--- a/usr/src/lib/libdladm/common/libdllink.c
+++ b/usr/src/lib/libdladm/common/libdllink.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
@@ -35,6 +33,7 @@
#include <sys/stat.h>
#include <sys/dld.h>
#include <sys/vlan.h>
+#include <zone.h>
#include <librcm.h>
#include <libdlpi.h>
#include <libdevinfo.h>
@@ -259,51 +258,79 @@ dladm_linkduplex2str(link_duplex_t duplex, char *buf)
* non-global zone.
*/
dladm_status_t
-dladm_setzid(const char *link, zoneid_t zoneid)
+dladm_setzid(const char *dlname, char *zone_name)
{
- int fd;
- dladm_status_t status = DLADM_STATUS_OK;
- dld_ioc_setzid_t dis;
-
- if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0)
- return (dladm_errno2status(errno));
-
- bzero(&dis, sizeof (dld_ioc_setzid_t));
- (void) strlcpy(dis.dis_link, link, MAXLINKNAMELEN);
- dis.dis_zid = zoneid;
-
- if (i_dladm_ioctl(fd, DLDIOC_SETZID, &dis, sizeof (dis)) < 0)
- status = dladm_errno2status(errno);
-
- (void) close(fd);
- return (status);
-}
+ datalink_id_t linkid;
+ char *val;
+ char **prop_val;
+ char link[MAXLINKNAMELEN];
+ uint_t ppa;
+ char dev[DLPI_LINKNAME_MAX];
+ int valsize;
+ dladm_status_t status = DLADM_STATUS_OK;
+ char *prop_name = "zone";
+ boolean_t needfree = B_FALSE;
+ char delim = ':';
+
+ /* If the link does not exist, it is a ppa-hacked vlan. */
+ status = dladm_name2info(dlname, &linkid, NULL, NULL, NULL);
+ switch (status) {
+ case DLADM_STATUS_NOTFOUND:
+ if (strlen(dlname) > MAXLINKNAMELEN)
+ return (DLADM_STATUS_BADVAL);
+
+ if (strlen(zone_name) > ZONENAME_MAX)
+ return (DLADM_STATUS_BADVAL);
+
+ status = dladm_parselink(dlname, dev, &ppa);
+ if (status != DLADM_STATUS_OK)
+ return (status);
-/*
- * Get zoneid of a given link
- */
-dladm_status_t
-dladm_getzid(datalink_id_t linkid, zoneid_t *zoneidp)
-{
- int fd;
- dladm_status_t status = DLADM_STATUS_OK;
- dld_ioc_getzid_t dig;
+ ppa = (uint_t)DLS_PPA2INST(ppa);
+ (void) snprintf(link, sizeof (link), "%s%d", dev, ppa);
- if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0)
- return (dladm_errno2status(errno));
+ status = dladm_name2info(link, &linkid, NULL, NULL, NULL);
+ if (status != DLADM_STATUS_OK)
+ return (status);
- bzero(&dig, sizeof (dld_ioc_getzid_t));
- dig.dig_linkid = linkid;
- dig.dig_zid = -1;
+ /*
+ * Since the link does not exist as yet, we've to pass the
+ * link name too as part of data, so that the kernel can
+ * create the link. Hence, we're packing the zone_name and
+ * the link name into val.
+ */
+ valsize = ZONENAME_MAX + MAXLINKNAMELEN + 1;
+ val = malloc(valsize);
+ if (val == NULL)
+ return (DLADM_STATUS_NOMEM);
+ needfree = B_TRUE;
- if (i_dladm_ioctl(fd, DLDIOC_GETZID, &dig, sizeof (dig)) < 0)
- status = dladm_errno2status(errno);
+ (void) snprintf(val, valsize, "%s%c%s", zone_name,
+ delim, dlname);
- (void) close(fd);
+ break;
+ case DLADM_STATUS_OK:
+ /*
+ * The link exists, so only the zone_name is being passed as
+ * val. We could also pass zone_name + linkname like in the
+ * previous case just to maintain consistency, but other calls
+ * like set_linkprop() in dladm.c [which is called when we run
+ * 'dladm set-linkprop -p zone <linkname>' at the command line]
+ * pass in the value entered at the command line [which is zone
+ * name] as val.
+ */
+ val = zone_name;
+ break;
+ default:
+ return (DLADM_STATUS_FAILED);
+ }
- if (status == DLADM_STATUS_OK)
- *zoneidp = dig.dig_zid;
+ prop_val = &val;
+ status = dladm_set_linkprop(linkid, prop_name, prop_val, 1,
+ DLADM_OPT_ACTIVE);
+ if (needfree)
+ free(val);
return (status);
}
diff --git a/usr/src/lib/libdladm/common/libdllink.h b/usr/src/lib/libdladm/common/libdllink.h
index 9359c9c299..32d74ea2c9 100644
--- a/usr/src/lib/libdladm/common/libdllink.h
+++ b/usr/src/lib/libdladm/common/libdllink.h
@@ -26,8 +26,6 @@
#ifndef _LIBDLLINK_H
#define _LIBDLLINK_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* This file includes structures, macros and routines used by general
* link administration (i.e. not limited to one specific type of link).
@@ -91,8 +89,7 @@ extern dladm_status_t dladm_walk(dladm_walkcb_t *, void *, datalink_class_t,
datalink_media_t, uint32_t);
extern dladm_status_t dladm_mac_walk(dladm_walkcb_t *, void *);
extern dladm_status_t dladm_info(datalink_id_t, dladm_attr_t *);
-extern dladm_status_t dladm_setzid(const char *, zoneid_t);
-extern dladm_status_t dladm_getzid(datalink_id_t, zoneid_t *);
+extern dladm_status_t dladm_setzid(const char *, char *);
extern dladm_status_t dladm_rename_link(const char *, const char *);
diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c
index b20fe4fe82..42851ce54c 100644
--- a/usr/src/lib/libdladm/common/linkprop.c
+++ b/usr/src/lib/libdladm/common/linkprop.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
@@ -48,7 +46,6 @@
#include <inet/wifi_ioctl.h>
#include <libdladm.h>
#include <sys/param.h>
-#include <sys/dld.h>
#include <inttypes.h>
#include <sys/ethernet.h>
@@ -101,31 +98,35 @@ typedef dladm_status_t pd_checkf_t(struct prop_desc *pd,
uint_t cnt, val_desc_t *propval,
datalink_media_t);
-typedef struct dld_public_prop_s {
+typedef struct dladm_public_prop_s {
mac_prop_id_t pp_id;
size_t pp_valsize;
char *pp_name;
char *pp_desc;
-} dld_public_prop_t;
+} dladm_public_prop_t;
-static dld_ioc_macprop_t *dld_buf_alloc(size_t, datalink_id_t, const char *,
+static dld_ioc_macprop_t *i_dladm_buf_alloc(size_t, datalink_id_t, const char *,
uint_t, dladm_status_t *);
-static dladm_status_t dld_set_prop(datalink_id_t, const char *, char **,
+static dladm_status_t i_dladm_set_prop(datalink_id_t, const char *, char **,
uint_t, uint_t);
-static dladm_status_t dld_get_prop(datalink_id_t, const char *, char **,
+static dladm_status_t i_dladm_get_prop(datalink_id_t, const char *, char **,
uint_t *, dladm_prop_type_t, uint_t);
+static dladm_public_prop_t *dladm_name2prop(const char *);
+static dld_ioc_macprop_t *i_dladm_get_public_prop(datalink_id_t, char *, uint_t,
+ dladm_status_t *);
static pd_getf_t do_get_zone, do_get_autopush, do_get_rate_mod,
do_get_rate_prop, do_get_channel_prop,
do_get_powermode_prop, do_get_radio_prop,
- dld_duplex_get, dld_status_get,
- dld_binary_get, dld_uint32_get, dld_flowctl_get;
-static pd_setf_t do_set_zone, do_set_autopush, do_set_rate_prop,
+ i_dladm_duplex_get, i_dladm_status_get,
+ i_dladm_binary_get, i_dladm_uint32_get,
+ i_dladm_flowctl_get;
+static pd_setf_t do_set_zone, do_set_rate_prop,
do_set_powermode_prop, do_set_radio_prop,
- dld_set_public_prop;
+ i_dladm_set_public_prop;
static pd_checkf_t do_check_zone, do_check_autopush, do_check_rate,
- dld_defmtu_check;
+ i_dladm_defmtu_check;
-static dladm_status_t dld_speed_get(struct prop_desc *, datalink_id_t,
+static dladm_status_t i_dladm_speed_get(struct prop_desc *, datalink_id_t,
char **, uint_t *, uint_t);
typedef struct prop_desc {
@@ -179,7 +180,6 @@ typedef struct prop_desc {
uint_t pd_flags;
#define PD_TEMPONLY 0x1 /* property is temporary only */
#define PD_CHECK_ALLOC 0x2 /* alloc vd_val as part of pd_check */
-#define PD_EMPTY_RESET 0x4 /* Use "" to reset the link property */
/*
* indicate link classes this property applies to.
*/
@@ -194,7 +194,7 @@ typedef struct prop_desc {
#define MAC_PROP_BUFSIZE(v) sizeof (dld_ioc_macprop_t) + (v) - 1
-static dld_public_prop_t dld_prop[] = {
+static dladm_public_prop_t dladm_prop[] = {
{ MAC_PROP_DUPLEX, sizeof (link_duplex_t),
"duplex", "link duplex mode" },
@@ -213,6 +213,12 @@ static dld_public_prop_t dld_prop[] = {
{ MAC_PROP_FLOWCTRL, sizeof (link_flowctrl_t),
"flowctrl", "flowcontrol" },
+ { MAC_PROP_ZONE, sizeof (dld_ioc_zid_t),
+ "zone", "non-global zones" },
+
+ { MAC_PROP_AUTOPUSH, sizeof (struct dlautopush),
+ "autopush", "autopush modules" },
+
{ MAC_PROP_ADV_1000FDX_CAP, sizeof (uint8_t),
"adv_1000fdx_cap", "Adv 1000 Mbps fdx" },
@@ -310,97 +316,98 @@ static prop_desc_t prop_table[] = {
DATALINK_CLASS_PHYS, DATALINK_ANY_MEDIATYPE },
{ "autopush", { "", 0 }, NULL, 0,
- do_set_autopush, NULL,
- do_get_autopush, do_check_autopush, PD_CHECK_ALLOC|PD_EMPTY_RESET,
+ i_dladm_set_public_prop, NULL,
+ do_get_autopush, do_check_autopush, PD_CHECK_ALLOC,
DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE },
{ "zone", { "", 0 }, NULL, 0,
do_set_zone, NULL,
- do_get_zone, do_check_zone, PD_TEMPONLY|PD_EMPTY_RESET,
+ do_get_zone, do_check_zone, PD_TEMPONLY|PD_CHECK_ALLOC,
DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE },
{ "duplex", { "", 0 },
link_duplex_vals, VALCNT(link_duplex_vals),
- NULL, NULL, dld_duplex_get, NULL,
+ NULL, NULL, i_dladm_duplex_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "state", { "up", LINK_STATE_UP },
link_status_vals, VALCNT(link_status_vals),
- NULL, NULL, dld_status_get, NULL,
+ NULL, NULL, i_dladm_status_get, NULL,
0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE },
{ "adv_autoneg_cap", { "1", 1 },
link_01_vals, VALCNT(link_01_vals),
- dld_set_public_prop, NULL, dld_binary_get, NULL,
+ i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "mtu", { "", 0 }, NULL, 0,
- dld_set_public_prop, NULL, dld_uint32_get,
- dld_defmtu_check, 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE },
+ i_dladm_set_public_prop, NULL, i_dladm_uint32_get,
+ i_dladm_defmtu_check, 0, DATALINK_CLASS_ALL,
+ DATALINK_ANY_MEDIATYPE },
{ "flowctrl", { "", 0 },
link_flow_vals, VALCNT(link_flow_vals),
- dld_set_public_prop, NULL, dld_flowctl_get, NULL,
+ i_dladm_set_public_prop, NULL, i_dladm_flowctl_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "adv_1000fdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- NULL, NULL, dld_binary_get, NULL,
+ NULL, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "en_1000fdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- dld_set_public_prop, NULL, dld_binary_get, NULL,
+ i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "adv_1000hdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- NULL, NULL, dld_binary_get, NULL,
+ NULL, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "en_1000hdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- dld_set_public_prop, NULL, dld_binary_get, NULL,
+ i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "adv_100fdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- NULL, NULL, dld_binary_get, NULL,
+ NULL, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "en_100fdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- dld_set_public_prop, NULL, dld_binary_get, NULL,
+ i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "adv_100hdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- NULL, NULL, dld_binary_get, NULL,
+ NULL, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "en_100hdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- dld_set_public_prop, NULL, dld_binary_get, NULL,
+ i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "adv_10fdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- NULL, NULL, dld_binary_get, NULL,
+ NULL, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "en_10fdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- dld_set_public_prop, NULL, dld_binary_get, NULL,
+ i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "adv_10hdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- NULL, NULL, dld_binary_get, NULL,
+ NULL, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER },
{ "en_10hdx_cap", { "", 0 },
link_01_vals, VALCNT(link_01_vals),
- dld_set_public_prop, NULL, dld_binary_get, NULL,
+ i_dladm_set_public_prop, NULL, i_dladm_binary_get, NULL,
0, DATALINK_CLASS_PHYS, DL_ETHER }
};
@@ -506,18 +513,26 @@ i_dladm_set_single_prop(datalink_id_t linkid, datalink_class_t class,
if (pdp->pd_defval.vd_name == NULL)
return (DLADM_STATUS_NOTSUP);
- if ((pdp->pd_flags & PD_EMPTY_RESET) != 0 ||
+ cnt = 1;
+ if ((pdp->pd_flags & PD_CHECK_ALLOC) != 0 ||
strlen(pdp->pd_defval.vd_name) > 0) {
if ((vdp = malloc(sizeof (val_desc_t))) == NULL)
return (DLADM_STATUS_NOMEM);
- (void) memcpy(vdp, &pdp->pd_defval,
- sizeof (val_desc_t));
+
+ if (pdp->pd_check != NULL) {
+ status = pdp->pd_check(pdp, linkid, prop_val,
+ cnt, vdp, media);
+ if (status != DLADM_STATUS_OK)
+ goto done;
+ } else {
+ (void) memcpy(vdp, &pdp->pd_defval,
+ sizeof (val_desc_t));
+ }
} else {
status = i_dladm_getset_defval(pdp, linkid,
media, flags);
return (status);
}
- cnt = 1;
}
status = pdp->pd_set(pdp, linkid, vdp, cnt, flags, media);
if (needfree) {
@@ -567,7 +582,7 @@ i_dladm_set_linkprop(datalink_id_t linkid, const char *prop_name,
if (!found) {
if (prop_name[0] == '_') {
/* other private properties */
- status = dld_set_prop(linkid, prop_name, prop_val,
+ status = i_dladm_set_prop(linkid, prop_name, prop_val,
val_cnt, flags);
} else {
status = DLADM_STATUS_NOTFOUND;
@@ -670,7 +685,7 @@ dladm_get_linkprop(datalink_id_t linkid, dladm_prop_type_t type,
/*
* private property.
*/
- return (dld_get_prop(linkid, prop_name,
+ return (i_dladm_get_prop(linkid, prop_name,
prop_val, val_cntp, type, dld_flags));
} else {
return (DLADM_STATUS_NOTFOUND);
@@ -819,14 +834,20 @@ do_get_zone(struct prop_desc *pd, datalink_id_t linkid,
char zone_name[ZONENAME_MAX];
zoneid_t zid;
dladm_status_t status;
+ char *cp;
+ dld_ioc_macprop_t *dip;
if (flags != 0)
return (DLADM_STATUS_NOTSUP);
- status = dladm_getzid(linkid, &zid);
+ dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
if (status != DLADM_STATUS_OK)
return (status);
+ cp = dip->pr_val;
+ (void) memcpy(&zid, cp, sizeof (zid));
+ free(dip);
+
*val_cnt = 1;
if (zid != GLOBAL_ZONEID) {
if (getzonenamebyid(zid, zone_name, sizeof (zone_name)) < 0)
@@ -912,41 +933,60 @@ static dladm_status_t
do_set_zone(prop_desc_t *pd, datalink_id_t linkid, val_desc_t *vdp,
uint_t val_cnt, uint_t flags, datalink_media_t media)
{
- dladm_status_t status;
+ dladm_status_t status = DLADM_STATUS_OK;
zoneid_t zid_old, zid_new;
char link[MAXLINKNAMELEN];
+ char *cp;
+ dld_ioc_macprop_t *dip;
+ dld_ioc_zid_t *dzp;
if (val_cnt != 1)
return (DLADM_STATUS_BADVALCNT);
- status = dladm_getzid(linkid, &zid_old);
- if (status != DLADM_STATUS_OK)
- return (status);
+ dzp = (dld_ioc_zid_t *)vdp->vd_val;
+
+ /*
+ * If diz_is_ppa_hack is set, then an implicit vlan must be created.
+ * There is no old value to compare against, and vdp->vd_val is
+ * already populated with the zoneid and linkname in the function
+ * do_check_zone().
+ */
+
+ if (dzp->diz_is_ppa_hack) {
+ zid_old = GLOBAL_ZONEID;
+ } else {
+ dip = i_dladm_get_public_prop(linkid, pd->pd_name,
+ flags, &status);
+ if (status != DLADM_STATUS_OK)
+ return (status);
+
+ cp = dip->pr_val;
+ (void) memcpy(&zid_old, cp, sizeof (zid_old));
+ free(dip);
+ }
+
+ zid_new = dzp->diz_zid;
+ (void) strlcpy(link, dzp->diz_link, MAXLINKNAMELEN);
/* Do nothing if setting to current value */
- zid_new = vdp->vd_val;
if (zid_new == zid_old)
- return (DLADM_STATUS_OK);
-
- if ((status = dladm_datalink_id2info(linkid, NULL, NULL, NULL,
- link, MAXLINKNAMELEN)) != DLADM_STATUS_OK) {
return (status);
- }
if (zid_new != GLOBAL_ZONEID) {
/*
* If the new zoneid is the global zone, we could destroy
* the link (in the case of an implicitly-created VLAN) as a
- * result of the dladm_setzid() operation. In that case,
- * we defer the operation to the end of this function to avoid
- * recreating the VLAN and getting a different linkid during
- * the rollback if other operation fails.
+ * result of setting the zoneid. In that case, we defer the
+ * operation to the end of this function to avoid recreating
+ * the VLAN and getting a different linkid during the rollback
+ * if other operation fails.
*
- * Otherwise, dladm_setzid() will hold a reference to the
+ * Otherwise, this operation will hold a reference to the
* link and prevent a link renaming, so we need to do it
* before other operations.
*/
- status = dladm_setzid(link, zid_new);
+ status = i_dladm_set_public_prop(pd, linkid, vdp, val_cnt,
+ flags, media);
if (status != DLADM_STATUS_OK)
return (status);
}
@@ -971,9 +1011,17 @@ do_set_zone(prop_desc_t *pd, datalink_id_t linkid, val_desc_t *vdp,
goto rollback2;
}
+ if (dzp->diz_is_ppa_hack) {
+ if ((status = dladm_name2info(link, &linkid, NULL, NULL,
+ NULL)) != DLADM_STATUS_OK) {
+ return (status);
+ }
+ }
+
(void) i_dladm_update_deventry(zid_new, linkid, B_TRUE);
} else {
- status = dladm_setzid(link, zid_new);
+ status = i_dladm_set_public_prop(pd, linkid, vdp, val_cnt,
+ flags, media);
if (status != DLADM_STATUS_OK)
goto rollback2;
}
@@ -986,8 +1034,12 @@ rollback2:
if (zid_old != GLOBAL_ZONEID)
(void) zone_add_datalink(zid_old, link);
rollback1:
- if (zid_new != GLOBAL_ZONEID)
- (void) dladm_setzid(link, zid_old);
+ if (zid_new != GLOBAL_ZONEID) {
+ dzp->diz_zid = zid_old;
+ (void) i_dladm_set_public_prop(pd, linkid, vdp, val_cnt,
+ flags, media);
+ }
+
return (status);
}
@@ -996,29 +1048,83 @@ static dladm_status_t
do_check_zone(struct prop_desc *pd, datalink_id_t linkid, char **prop_val,
uint_t val_cnt, val_desc_t *vdp, datalink_media_t media)
{
- zoneid_t zid;
+ char *zone_name;
+ char linkname[MAXLINKNAMELEN];
+ zoneid_t zoneid;
+ char *cp;
+ dladm_status_t status = DLADM_STATUS_OK;
+ boolean_t is_ppa_hack = B_FALSE;
+ dld_ioc_zid_t *dzp;
if (val_cnt != 1)
return (DLADM_STATUS_BADVALCNT);
- if ((zid = getzoneidbyname(*prop_val)) == -1)
- return (DLADM_STATUS_BADVAL);
+ dzp = malloc(sizeof (dld_ioc_zid_t));
+ if (dzp == NULL)
+ return (DLADM_STATUS_NOMEM);
- if (zid != GLOBAL_ZONEID) {
+ if (prop_val) {
+ /*
+ * The prop_val contains zone_name{:linkname}. The linkname is
+ * present only when the link is a ppa-hacked vlan.
+ */
+ cp = strchr(*prop_val, ':');
+ if (cp) {
+ (void) strlcpy(linkname, cp + 1, MAXLINKNAMELEN);
+ *cp = '\0';
+ is_ppa_hack = B_TRUE;
+ } else {
+ status = dladm_datalink_id2info(linkid, NULL, NULL,
+ NULL, linkname, MAXLINKNAMELEN);
+ if (status != DLADM_STATUS_OK) {
+ goto done;
+ }
+ }
+ zone_name = *prop_val;
+ } else {
+ zone_name = GLOBAL_ZONENAME;
+ if ((status = dladm_datalink_id2info(linkid, NULL, NULL, NULL,
+ linkname, MAXLINKNAMELEN)) != DLADM_STATUS_OK) {
+ goto done;
+ }
+ }
+
+ if (strlen(linkname) > MAXLINKNAMELEN) {
+ status = DLADM_STATUS_BADVAL;
+ goto done;
+ }
+
+ if ((zoneid = getzoneidbyname(zone_name)) == -1) {
+ status = DLADM_STATUS_BADVAL;
+ goto done;
+ }
+
+ if (zoneid != GLOBAL_ZONEID) {
ushort_t flags;
- if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags,
+ if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags,
sizeof (flags)) < 0) {
- return (dladm_errno2status(errno));
+ status = dladm_errno2status(errno);
+ goto done;
}
if (!(flags & ZF_NET_EXCL)) {
- return (DLADM_STATUS_BADVAL);
+ status = DLADM_STATUS_BADVAL;
+ goto done;
}
}
- vdp->vd_val = zid;
+ (void) memset(dzp, 0, sizeof (dld_ioc_zid_t));
+
+ dzp->diz_zid = zoneid;
+ (void) strlcpy(dzp->diz_link, linkname, MAXLINKNAMELEN);
+ dzp->diz_is_ppa_hack = is_ppa_hack;
+
+ vdp->vd_val = (uintptr_t)dzp;
return (DLADM_STATUS_OK);
+done:
+ free(dzp);
+ return (status);
}
/* ARGSUSED */
@@ -1026,32 +1132,32 @@ static dladm_status_t
do_get_autopush(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags)
{
- dld_ioc_ap_t dia;
- int fd, i, len;
+ struct dlautopush dlap;
+ int i, len;
+ dladm_status_t status;
+ dld_ioc_macprop_t *dip;
if (flags & MAC_PROP_DEFAULT)
return (DLADM_STATUS_NOTSUP);
- if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0)
- return (dladm_errno2status(errno));
-
*val_cnt = 1;
- dia.dia_linkid = linkid;
- if (i_dladm_ioctl(fd, DLDIOC_GETAUTOPUSH, &dia, sizeof (dia)) < 0) {
+ dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
+ if (dip == NULL) {
(*prop_val)[0] = '\0';
goto done;
}
+ (void) memcpy(&dlap, dip->pr_val, sizeof (dlap));
- for (i = 0, len = 0; i < dia.dia_npush; i++) {
+ for (i = 0, len = 0; i < dlap.dap_npush; i++) {
if (i != 0) {
(void) snprintf(*prop_val + len,
DLADM_PROP_VAL_MAX - len, "%c", AP_DELIMITER);
len += 1;
}
(void) snprintf(*prop_val + len, DLADM_PROP_VAL_MAX - len,
- "%s", dia.dia_aplist[i]);
- len += strlen(dia.dia_aplist[i]);
- if (dia.dia_anchor - 1 == i) {
+ "%s", dlap.dap_aplist[i]);
+ len += strlen(dlap.dap_aplist[i]);
+ if (dlap.dap_anchor - 1 == i) {
(void) snprintf(*prop_val + len,
DLADM_PROP_VAL_MAX - len, "%c%s", AP_DELIMITER,
AP_ANCHOR);
@@ -1059,48 +1165,11 @@ do_get_autopush(struct prop_desc *pd, datalink_id_t linkid,
}
}
+ free(dip);
done:
- (void) close(fd);
return (DLADM_STATUS_OK);
}
-/* ARGSUSED */
-static dladm_status_t
-do_set_autopush(prop_desc_t *pd, datalink_id_t linkid, val_desc_t *vdp,
- uint_t val_cnt, uint_t flags, datalink_media_t media)
-{
- dld_ioc_ap_t dia;
- struct dlautopush *dlap = (struct dlautopush *)vdp->vd_val;
- dladm_status_t status = DLADM_STATUS_OK;
- int fd, i;
- int ic_cmd;
-
- if (val_cnt != 1)
- return (DLADM_STATUS_BADVALCNT);
-
- if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0)
- return (dladm_errno2status(errno));
-
- dia.dia_linkid = linkid;
- if (dlap != NULL) {
- dia.dia_anchor = dlap->dap_anchor;
- dia.dia_npush = dlap->dap_npush;
- for (i = 0; i < dia.dia_npush; i++) {
- (void) strlcpy(dia.dia_aplist[i], dlap->dap_aplist[i],
- FMNAMESZ+1);
- }
- ic_cmd = DLDIOC_SETAUTOPUSH;
- } else {
- ic_cmd = DLDIOC_CLRAUTOPUSH;
- }
-
- if (i_dladm_ioctl(fd, ic_cmd, &dia, sizeof (dia)) < 0)
- status = dladm_errno2status(errno);
-
- (void) close(fd);
- return (status);
-}
-
/*
* Add the specified module to the dlautopush structure; returns a
* DLADM_STATUS_* code.
@@ -1152,22 +1221,26 @@ do_check_autopush(struct prop_desc *pd, datalink_id_t linkid, char **prop_val,
if (val_cnt != 1)
return (DLADM_STATUS_BADVALCNT);
- dlap = malloc(sizeof (struct dlautopush));
- if (dlap == NULL)
- return (DLADM_STATUS_NOMEM);
+ if (prop_val != NULL) {
+ dlap = malloc(sizeof (struct dlautopush));
+ if (dlap == NULL)
+ return (DLADM_STATUS_NOMEM);
- (void) memset(dlap, 0, sizeof (struct dlautopush));
- (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER);
- bcopy(*prop_val, val, DLADM_PROP_VAL_MAX);
- module = strtok(val, delimiters);
- while (module != NULL) {
- status = i_dladm_add_ap_module(module, dlap);
- if (status != DLADM_STATUS_OK)
- return (status);
- module = strtok(NULL, delimiters);
- }
+ (void) memset(dlap, 0, sizeof (struct dlautopush));
+ (void) snprintf(delimiters, 4, " %c\n", AP_DELIMITER);
+ bcopy(*prop_val, val, DLADM_PROP_VAL_MAX);
+ module = strtok(val, delimiters);
+ while (module != NULL) {
+ status = i_dladm_add_ap_module(module, dlap);
+ if (status != DLADM_STATUS_OK)
+ return (status);
+ module = strtok(NULL, delimiters);
+ }
- vdp->vd_val = (uintptr_t)dlap;
+ vdp->vd_val = (uintptr_t)dlap;
+ } else {
+ vdp->vd_val = 0;
+ }
return (DLADM_STATUS_OK);
}
@@ -1219,7 +1292,8 @@ do_get_rate_prop(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags)
{
if (media != DL_WIFI)
- return (dld_speed_get(pd, linkid, prop_val, val_cnt, flags));
+ return (i_dladm_speed_get(pd, linkid, prop_val,
+ val_cnt, flags));
return (do_get_rate_common(pd, linkid, prop_val, val_cnt,
WL_DESIRED_RATES));
@@ -1614,12 +1688,12 @@ done:
return (status);
}
-static dld_public_prop_t *
+static dladm_public_prop_t *
dladm_name2prop(const char *prop_name)
{
- dld_public_prop_t *p;
+ dladm_public_prop_t *p;
- for (p = dld_prop; p->pp_id != MAC_PROP_PRIVATE; p++) {
+ for (p = dladm_prop; p->pp_id != MAC_PROP_PRIVATE; p++) {
if (strcmp(p->pp_name, prop_name) == 0)
break;
}
@@ -1628,12 +1702,12 @@ dladm_name2prop(const char *prop_name)
static dld_ioc_macprop_t *
-dld_buf_alloc(size_t valsize, datalink_id_t linkid, const char *prop_name,
+i_dladm_buf_alloc(size_t valsize, datalink_id_t linkid, const char *prop_name,
uint_t flags, dladm_status_t *status)
{
int dsize;
dld_ioc_macprop_t *dip;
- dld_public_prop_t *p;
+ dladm_public_prop_t *p;
*status = DLADM_STATUS_OK;
p = dladm_name2prop(prop_name);
@@ -1658,7 +1732,7 @@ dld_buf_alloc(size_t valsize, datalink_id_t linkid, const char *prop_name,
/* ARGSUSED */
static dladm_status_t
-dld_set_public_prop(prop_desc_t *pd, datalink_id_t linkid,
+i_dladm_set_public_prop(prop_desc_t *pd, datalink_id_t linkid,
val_desc_t *vdp, uint_t val_cnt, uint_t flags, datalink_media_t media)
{
dld_ioc_macprop_t *dip;
@@ -1669,7 +1743,7 @@ dld_set_public_prop(prop_desc_t *pd, datalink_id_t linkid,
uint32_t u32;
void *val;
- dip = dld_buf_alloc(0, linkid, pd->pd_name, 0, &status);
+ dip = i_dladm_buf_alloc(0, linkid, pd->pd_name, 0, &status);
if (dip == NULL)
return (status);
@@ -1699,7 +1773,11 @@ dld_set_public_prop(prop_desc_t *pd, datalink_id_t linkid,
}
}
- (void) memcpy(dip->pr_val, val, dip->pr_valsize);
+ if (val != NULL)
+ (void) memcpy(dip->pr_val, val, dip->pr_valsize);
+ else
+ dip->pr_valsize = 0;
+
dsize = MAC_PROP_BUFSIZE(dip->pr_valsize);
if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) {
status = dladm_errno2status(errno);
@@ -1715,7 +1793,7 @@ done:
}
static dld_ioc_macprop_t *
-dld_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags,
+i_dladm_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags,
dladm_status_t *status)
{
int fd, dsize;
@@ -1723,7 +1801,7 @@ dld_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags,
*status = DLADM_STATUS_OK;
- dip = dld_buf_alloc(0, linkid, prop_name, flags, status);
+ dip = i_dladm_buf_alloc(0, linkid, prop_name, flags, status);
if (dip == NULL)
return (NULL);
@@ -1748,8 +1826,8 @@ done:
/* ARGSUSED */
static dladm_status_t
-dld_defmtu_check(struct prop_desc *pd, datalink_id_t linkid, char **prop_val,
- uint_t val_cnt, val_desc_t *v, datalink_media_t media)
+i_dladm_defmtu_check(struct prop_desc *pd, datalink_id_t linkid,
+ char **prop_val, uint_t val_cnt, val_desc_t *v, datalink_media_t media)
{
if (val_cnt != 1)
return (DLADM_STATUS_BADVAL);
@@ -1759,7 +1837,7 @@ dld_defmtu_check(struct prop_desc *pd, datalink_id_t linkid, char **prop_val,
/* ARGSUSED */
static dladm_status_t
-dld_duplex_get(struct prop_desc *pd, datalink_id_t linkid,
+i_dladm_duplex_get(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags)
{
link_duplex_t link_duplex;
@@ -1789,7 +1867,7 @@ dld_duplex_get(struct prop_desc *pd, datalink_id_t linkid,
/* ARGSUSED */
static dladm_status_t
-dld_speed_get(struct prop_desc *pd, datalink_id_t linkid,
+i_dladm_speed_get(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, uint_t flags)
{
uint64_t ifspeed = 0;
@@ -1815,7 +1893,7 @@ dld_speed_get(struct prop_desc *pd, datalink_id_t linkid,
/* ARGSUSED */
static dladm_status_t
-dld_status_get(struct prop_desc *pd, datalink_id_t linkid,
+i_dladm_status_get(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags)
{
link_state_t link_state;
@@ -1825,7 +1903,7 @@ dld_status_get(struct prop_desc *pd, datalink_id_t linkid,
if (flags & MAC_PROP_DEFAULT)
return (DLADM_STATUS_NOTSUP);
- dip = dld_get_public_prop(linkid, pd->pd_name, flags, &status);
+ dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
if (status != DLADM_STATUS_OK)
return (status);
cp = (uchar_t *)dip->pr_val;
@@ -1849,13 +1927,13 @@ dld_status_get(struct prop_desc *pd, datalink_id_t linkid,
/* ARGSUSED */
static dladm_status_t
-dld_binary_get(struct prop_desc *pd, datalink_id_t linkid,
+i_dladm_binary_get(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags)
{
dld_ioc_macprop_t *dip;
dladm_status_t status;
- dip = dld_get_public_prop(linkid, pd->pd_name, flags, &status);
+ dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
if (dip == NULL)
return (status);
(void) snprintf(*prop_val, DLADM_PROP_VAL_MAX, "%x", dip->pr_val[0]);
@@ -1866,7 +1944,7 @@ dld_binary_get(struct prop_desc *pd, datalink_id_t linkid,
/* ARGSUSED */
static dladm_status_t
-dld_uint32_get(struct prop_desc *pd, datalink_id_t linkid,
+i_dladm_uint32_get(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags)
{
dld_ioc_macprop_t *dip;
@@ -1874,7 +1952,7 @@ dld_uint32_get(struct prop_desc *pd, datalink_id_t linkid,
uchar_t *cp;
dladm_status_t status;
- dip = dld_get_public_prop(linkid, pd->pd_name, flags, &status);
+ dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
if (dip == NULL)
return (status);
cp = (uchar_t *)dip->pr_val;
@@ -1887,7 +1965,7 @@ dld_uint32_get(struct prop_desc *pd, datalink_id_t linkid,
/* ARGSUSED */
static dladm_status_t
-dld_flowctl_get(struct prop_desc *pd, datalink_id_t linkid,
+i_dladm_flowctl_get(struct prop_desc *pd, datalink_id_t linkid,
char **prop_val, uint_t *val_cnt, datalink_media_t media, uint_t flags)
{
dld_ioc_macprop_t *dip;
@@ -1895,7 +1973,7 @@ dld_flowctl_get(struct prop_desc *pd, datalink_id_t linkid,
dladm_status_t status;
uchar_t *cp;
- dip = dld_get_public_prop(linkid, pd->pd_name, flags, &status);
+ dip = i_dladm_get_public_prop(linkid, pd->pd_name, flags, &status);
if (dip == NULL)
return (status);
cp = (uchar_t *)dip->pr_val;
@@ -1922,14 +2000,14 @@ dld_flowctl_get(struct prop_desc *pd, datalink_id_t linkid,
/* ARGSUSED */
static dladm_status_t
-dld_set_prop(datalink_id_t linkid, const char *prop_name,
+i_dladm_set_prop(datalink_id_t linkid, const char *prop_name,
char **prop_val, uint_t val_cnt, uint_t flags)
{
int fd, i, slen;
int bufsize = 0, dsize;
dld_ioc_macprop_t *dip = NULL;
uchar_t *dp;
- dld_public_prop_t *p;
+ dladm_public_prop_t *p;
dladm_status_t status = DLADM_STATUS_OK;
if ((prop_name == NULL && prop_val != NULL) ||
@@ -1954,7 +2032,7 @@ dld_set_prop(datalink_id_t linkid, const char *prop_name,
bufsize += 1024;
}
- dip = dld_buf_alloc(bufsize + 1, linkid, prop_name,
+ dip = i_dladm_buf_alloc(bufsize + 1, linkid, prop_name,
(prop_val != NULL ? 0 : MAC_PROP_DEFAULT), &status);
if (dip == NULL)
return (status);
@@ -1998,14 +2076,14 @@ done:
}
static dladm_status_t
-dld_get_prop(datalink_id_t linkid, const char *prop_name,
+i_dladm_get_prop(datalink_id_t linkid, const char *prop_name,
char **prop_val, uint_t *val_cnt, dladm_prop_type_t type, uint_t dld_flags)
{
int fd;
dladm_status_t status = DLADM_STATUS_OK;
uint_t dsize;
dld_ioc_macprop_t *dip = NULL;
- dld_public_prop_t *p;
+ dladm_public_prop_t *p;
char tmp = '\0';
if ((prop_name == NULL && prop_val != NULL) ||
@@ -2025,7 +2103,7 @@ dld_get_prop(datalink_id_t linkid, const char *prop_name,
/*
* private properties: all parsing is done in the kernel.
*/
- dip = dld_buf_alloc(1024, linkid, prop_name, dld_flags, &status);
+ dip = i_dladm_buf_alloc(1024, linkid, prop_name, dld_flags, &status);
if (dip == NULL)
return (status);
dsize = MAC_PROP_BUFSIZE(dip->pr_valsize);
@@ -2074,14 +2152,14 @@ i_dladm_getset_defval(prop_desc_t *pdp, datalink_id_t linkid,
}
/*
- * PD_EMPTY_RESET is used for properties like zone where the
- * "" itself is used to reset the property. So libdladm can
- * copy pdp->pd_defval over to the val_desc_t passed down on
- * the setprop using the global values in the table. For other
- * cases (PD_EMPTY_RESET is not set, vd_name is ""), doing
- * reset-linkprop will cause libdladm to do a getprop to find
- * the default value and then do a setprop to reset the value
- * to default.
+ * For properties which have pdp->pd_defval.vd_name as a non-empty
+ * string, the "" itself is used to reset the property (exceptions
+ * are zone and autopush, which populate vdp->vd_val). So
+ * libdladm can copy pdp->pd_defval over to the val_desc_t passed
+ * down on the setprop using the global values in the table. For
+ * other cases (vd_name is ""), doing reset-linkprop will cause
+ * libdladm to do a getprop to find the default value and then do
+ * a setprop to reset the value to default.
*/
status = pdp->pd_get(pdp, linkid, prop_vals, &cnt, media,
MAC_PROP_DEFAULT);
diff --git a/usr/src/lib/libdladm/common/mapfile-vers b/usr/src/lib/libdladm/common/mapfile-vers
index ce7f994420..9c61b84883 100644
--- a/usr/src/lib/libdladm/common/mapfile-vers
+++ b/usr/src/lib/libdladm/common/mapfile-vers
@@ -22,15 +22,12 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
SUNWprivate_1.1 {
global:
dladm_info;
dladm_walk;
dladm_setzid;
- dladm_getzid;
dladm_status2str;
dladm_linkstate2str;
dladm_linkduplex2str;