summaryrefslogtreecommitdiff
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
parent43afaaa8b73f73af765f4fa90f39a0f86cb8a364 (diff)
downloadillumos-joyent-3bc21d0a9c7b31b1132c254e389a4114c23bcf00.tar.gz
6714745 zone/autopush should be implemented using DLDIOC_*MACPROP ioctls.
-rw-r--r--usr/src/cmd/truss/codes.c11
-rw-r--r--usr/src/cmd/zoneadmd/vplat.c95
-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
-rw-r--r--usr/src/uts/common/io/dld/dld_drv.c190
-rw-r--r--usr/src/uts/common/sys/dld.h42
-rw-r--r--usr/src/uts/common/sys/mac.h4
9 files changed, 419 insertions, 456 deletions
diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c
index 680fe44cb5..125ef9a33f 100644
--- a/usr/src/cmd/truss/codes.c
+++ b/usr/src/cmd/truss/codes.c
@@ -27,8 +27,6 @@
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -851,13 +849,12 @@ const struct ioc {
"dld_ioc_create_vlan"},
{ (uint_t)DLDIOC_DELETE_VLAN, "DLDIOC_DELETE_VLAN",
"dld_ioc_delete_vlan"},
- { (uint_t)DLDIOC_SETAUTOPUSH, "DLDIOC_SETAUTOPUSH", "dld_ioc_ap"},
- { (uint_t)DLDIOC_GETAUTOPUSH, "DLDIOC_GETAUTOPUSH", "dld_ioc_ap"},
- { (uint_t)DLDIOC_CLRAUTOPUSH, "DLDIOC_CLRAUTOPUSH", "dld_ioc_ap"},
{ (uint_t)DLDIOC_DOORSERVER, "DLDIOC_DOORSERVER", "dld_ioc_door"},
{ (uint_t)DLDIOC_RENAME, "DLDIOC_RENAME", "dld_ioc_rename"},
- { (uint_t)DLDIOC_SETZID, "DLDIOC_SETZID", "dld_ioc_setzid"},
- { (uint_t)DLDIOC_GETZID, "DLDIOC_GETZID", "dld_ioc_getzid"},
+ { (uint_t)DLDIOC_SETMACPROP, "DLDIOC_SETMACPROP",
+ "dld_ioc_macprop_s"},
+ { (uint_t)DLDIOC_GETMACPROP, "DLDIOC_GETMACPROP",
+ "dld_ioc_macprop_s"},
/* ZFS ioctls */
{ (uint_t)ZFS_IOC_POOL_CREATE, "ZFS_IOC_POOL_CREATE",
diff --git a/usr/src/cmd/zoneadmd/vplat.c b/usr/src/cmd/zoneadmd/vplat.c
index cd5a5681e9..616da5c564 100644
--- a/usr/src/cmd/zoneadmd/vplat.c
+++ b/usr/src/cmd/zoneadmd/vplat.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* This module contains functions used to bring up and tear down the
* Virtual Platform: [un]mounting file-systems, [un]plumbing network
@@ -2609,28 +2607,8 @@ configure_shared_network_interfaces(zlog_t *zlogp)
return (0);
}
-static void
-show_owner(zlog_t *zlogp, char *dlname)
-{
- zoneid_t dl_owner_zid;
- char dl_owner_zname[ZONENAME_MAX];
-
- dl_owner_zid = ALL_ZONES;
- if (zone_check_datalink(&dl_owner_zid, dlname) != 0)
- (void) snprintf(dl_owner_zname, ZONENAME_MAX, "<unknown>");
- else if (getzonenamebyid(dl_owner_zid, dl_owner_zname, ZONENAME_MAX)
- < 0)
- (void) snprintf(dl_owner_zname, ZONENAME_MAX, "<%d>",
- dl_owner_zid);
-
- errno = EPERM;
- zerror(zlogp, B_TRUE, "WARNING: skipping network interface '%s' "
- "which is used by the non-global zone '%s'.\n",
- dlname, dl_owner_zname);
-}
-
static int
-add_datalink(zlog_t *zlogp, zoneid_t zoneid, char *dlname)
+add_datalink(zlog_t *zlogp, char *zone_name, char *dlname)
{
/* First check if it's in use by global zone. */
if (zonecfg_ifname_exists(AF_INET, dlname) ||
@@ -2641,22 +2619,10 @@ add_datalink(zlog_t *zlogp, zoneid_t zoneid, char *dlname)
return (-1);
}
- /* Add access control information */
- if (zone_add_datalink(zoneid, dlname) != 0) {
- /* If someone got this link before us, show its name */
- if (errno == EPERM)
- show_owner(zlogp, dlname);
- else
- zerror(zlogp, B_TRUE, "WARNING: unable to add network "
- "interface '%s'.", dlname);
- return (-1);
- }
-
/* Set zoneid of this link. */
- if (dladm_setzid(dlname, zoneid) != DLADM_STATUS_OK) {
+ if (dladm_setzid(dlname, zone_name) != DLADM_STATUS_OK) {
zerror(zlogp, B_TRUE, "WARNING: unable to add network "
"interface '%s'.", dlname);
- (void) zone_remove_datalink(zoneid, dlname);
return (-1);
}
@@ -2664,22 +2630,10 @@ add_datalink(zlog_t *zlogp, zoneid_t zoneid, char *dlname)
}
static int
-remove_datalink(zlog_t *zlogp, zoneid_t zoneid, char *dlname)
+remove_datalink(zlog_t *zlogp, char *dlname)
{
- /*
- * Remove access control information.
- * If the errno is ENXIO, the interface is not added yet,
- * nothing to report then.
- */
- if (zone_remove_datalink(zoneid, dlname) != 0) {
- if (errno == ENXIO)
- return (0);
- zerror(zlogp, B_TRUE, "unable to remove network interface '%s'",
- dlname);
- return (-1);
- }
-
- if (dladm_setzid(dlname, GLOBAL_ZONEID) != DLADM_STATUS_OK) {
+ if (dladm_setzid(dlname, GLOBAL_ZONENAME)
+ != DLADM_STATUS_OK) {
zerror(zlogp, B_TRUE, "unable to release network "
"interface '%s'", dlname);
return (-1);
@@ -2697,17 +2651,11 @@ configure_exclusive_network_interfaces(zlog_t *zlogp)
{
zone_dochandle_t handle;
struct zone_nwiftab nwiftab;
- zoneid_t zoneid;
char rootpath[MAXPATHLEN];
char path[MAXPATHLEN];
di_prof_t prof = NULL;
boolean_t added = B_FALSE;
- if ((zoneid = getzoneidbyname(zone_name)) == -1) {
- zerror(zlogp, B_TRUE, "unable to get zoneid");
- return (-1);
- }
-
if ((handle = zonecfg_init_handle()) == NULL) {
zerror(zlogp, B_TRUE, "getting zone configuration handle");
return (-1);
@@ -2758,24 +2706,14 @@ configure_exclusive_network_interfaces(zlog_t *zlogp)
* created in that case. The /dev/net entry is always
* accessible.
*/
- if (add_datalink(zlogp, zoneid, nwiftab.zone_nwif_physical)
+ if (add_datalink(zlogp, zone_name, nwiftab.zone_nwif_physical)
== 0) {
- char name[DLPI_LINKNAME_MAX];
- datalink_id_t linkid;
-
- if (dladm_name2info(nwiftab.zone_nwif_physical,
- &linkid, NULL, NULL, NULL) == DLADM_STATUS_OK &&
- dladm_linkid2legacyname(linkid, name,
- sizeof (name)) == DLADM_STATUS_OK) {
- if (di_prof_add_dev(prof, name) != 0) {
- (void) zonecfg_endnwifent(handle);
- zonecfg_fini_handle(handle);
- zerror(zlogp, B_TRUE,
- "failed to add network device");
- return (-1);
- }
- added = B_TRUE;
- }
+ added = B_TRUE;
+ } else {
+ (void) zonecfg_endnwifent(handle);
+ zonecfg_fini_handle(handle);
+ zerror(zlogp, B_TRUE, "failed to add network device");
+ return (-1);
}
}
(void) zonecfg_endnwifent(handle);
@@ -2832,7 +2770,7 @@ again:
ptr = dlnames;
for (i = 0; i < dlnum; i++) {
/* Remove access control information */
- if (remove_datalink(zlogp, zoneid, ptr) != 0) {
+ if (remove_datalink(zlogp, ptr) != 0) {
free(dlnames);
return (-1);
}
@@ -2846,7 +2784,7 @@ again:
* Get the list of the data-links from configuration, and try to remove it
*/
static int
-unconfigure_exclusive_network_interfaces_static(zlog_t *zlogp, zoneid_t zoneid)
+unconfigure_exclusive_network_interfaces_static(zlog_t *zlogp)
{
zone_dochandle_t handle;
struct zone_nwiftab nwiftab;
@@ -2868,7 +2806,7 @@ unconfigure_exclusive_network_interfaces_static(zlog_t *zlogp, zoneid_t zoneid)
if (zonecfg_getnwifent(handle, &nwiftab) != Z_OK)
break;
/* Remove access control information */
- if (remove_datalink(zlogp, zoneid, nwiftab.zone_nwif_physical)
+ if (remove_datalink(zlogp, nwiftab.zone_nwif_physical)
!= 0) {
(void) zonecfg_endnwifent(handle);
zonecfg_fini_handle(handle);
@@ -2888,8 +2826,7 @@ static int
unconfigure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid)
{
if (unconfigure_exclusive_network_interfaces_run(zlogp, zoneid) != 0) {
- return (unconfigure_exclusive_network_interfaces_static(zlogp,
- zoneid));
+ return (unconfigure_exclusive_network_interfaces_static(zlogp));
}
return (0);
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;
diff --git a/usr/src/uts/common/io/dld/dld_drv.c b/usr/src/uts/common/io/dld/dld_drv.c
index 246a4054ad..0ab4c8ee14 100644
--- a/usr/src/uts/common/io/dld/dld_drv.c
+++ b/usr/src/uts/common/io/dld/dld_drv.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Data-Link Driver
*/
@@ -69,6 +67,9 @@ static void drv_secobj_fini(void);
static void drv_ioc_secobj_set(dld_ctl_str_t *, mblk_t *);
static void drv_ioc_secobj_get(dld_ctl_str_t *, mblk_t *);
static void drv_ioc_secobj_unset(dld_ctl_str_t *, mblk_t *);
+static int drv_ioc_setap(datalink_id_t, struct dlautopush *);
+static int drv_ioc_getap(datalink_id_t, struct dlautopush *);
+static int drv_ioc_clrap(datalink_id_t);
/*
* The following entry points are private to dld and are used for control
@@ -519,8 +520,11 @@ drv_ioc_prop_common(dld_ctl_str_t *ctls, mblk_t *mp, boolean_t set)
dls_vlan_t *dvp;
datalink_id_t linkid;
mac_prop_t macprop;
+ uchar_t *cp;
+ struct dlautopush *dlap;
+ dld_ioc_zid_t *dzp;
- if ((err = miocpullup(mp, sizeof (dld_ioc_macprop_t))) != 0)
+ if ((err = miocpullup(mp, sizeof (dld_ioc_macprop_t) - 1)) != 0)
goto done;
dipp = (dld_ioc_macprop_t *)mp->b_cont->b_rptr;
@@ -531,6 +535,37 @@ drv_ioc_prop_common(dld_ctl_str_t *ctls, mblk_t *mp, boolean_t set)
linkid = dipp->pr_linkid;
+ switch (dipp->pr_num) {
+ case MAC_PROP_ZONE:
+ if (set) {
+ dzp = (dld_ioc_zid_t *)dipp->pr_val;
+ err = dls_devnet_setzid(dzp->diz_link, dzp->diz_zid);
+ goto done;
+ } else {
+ cp = (uchar_t *)dipp->pr_val;
+ err = dls_devnet_getzid(linkid, (zoneid_t *)cp);
+ goto done;
+ }
+ case MAC_PROP_AUTOPUSH:
+ if (set) {
+ if (dipp->pr_valsize != 0) {
+ dlap = (struct dlautopush *)dipp->pr_val;
+ err = drv_ioc_setap(linkid, dlap);
+ goto done;
+ } else {
+ err = drv_ioc_clrap(linkid);
+ goto done;
+ }
+ } else {
+ dlap = (struct dlautopush *)dipp->pr_val;
+ err = drv_ioc_getap(linkid, dlap);
+ goto done;
+ }
+
+ default:
+ break;
+ }
+
if ((err = dls_devnet_hold_tmp(linkid, &dlh)) != 0)
goto done;
@@ -729,23 +764,14 @@ done:
miocnak(q, mp, 0, err);
}
-/*
- * DLDIOC_SETAUTOPUSH
- */
-static void
-drv_ioc_setap(dld_ctl_str_t *ctls, mblk_t *mp)
+static int
+drv_ioc_setap(datalink_id_t linkid, struct dlautopush *dlap)
{
- dld_ioc_ap_t *diap;
dld_ap_t *dap;
int i, err;
- queue_t *q = ctls->cs_wq;
mod_hash_key_t key;
- if ((err = miocpullup(mp, sizeof (dld_ioc_ap_t))) != 0)
- goto failed;
-
- diap = (dld_ioc_ap_t *)mp->b_cont->b_rptr;
- if (diap->dia_npush == 0 || diap->dia_npush > MAXAPUSH) {
+ if (dlap->dap_npush == 0 || dlap->dap_npush > MAXAPUSH) {
err = EINVAL;
goto failed;
}
@@ -753,14 +779,14 @@ drv_ioc_setap(dld_ctl_str_t *ctls, mblk_t *mp)
/*
* Validate that the specified list of modules exist.
*/
- for (i = 0; i < diap->dia_npush; i++) {
- if (fmodsw_find(diap->dia_aplist[i], FMODSW_LOAD) == NULL) {
+ for (i = 0; i < dlap->dap_npush; i++) {
+ if (fmodsw_find(dlap->dap_aplist[i], FMODSW_LOAD) == NULL) {
err = EINVAL;
goto failed;
}
}
- key = (mod_hash_key_t)(uintptr_t)diap->dia_linkid;
+ key = (mod_hash_key_t)(uintptr_t)linkid;
rw_enter(&dld_ap_hash_lock, RW_WRITER);
if (mod_hash_find(dld_ap_hashp, key, (mod_hash_val_t *)&dap) != 0) {
@@ -771,7 +797,7 @@ drv_ioc_setap(dld_ctl_str_t *ctls, mblk_t *mp)
goto failed;
}
- dap->da_linkid = diap->dia_linkid;
+ dap->da_linkid = linkid;
err = mod_hash_insert(dld_ap_hashp, key, (mod_hash_val_t)dap);
ASSERT(err == 0);
}
@@ -779,40 +805,29 @@ drv_ioc_setap(dld_ctl_str_t *ctls, mblk_t *mp)
/*
* Update the configuration.
*/
- dap->da_anchor = diap->dia_anchor;
- dap->da_npush = diap->dia_npush;
- for (i = 0; i < diap->dia_npush; i++) {
- (void) strlcpy(dap->da_aplist[i], diap->dia_aplist[i],
+ dap->da_anchor = dlap->dap_anchor;
+ dap->da_npush = dlap->dap_npush;
+ for (i = 0; i < dlap->dap_npush; i++) {
+ (void) strlcpy(dap->da_aplist[i], dlap->dap_aplist[i],
FMNAMESZ + 1);
}
rw_exit(&dld_ap_hash_lock);
- miocack(q, mp, 0, 0);
- return;
+ return (0);
failed:
- miocnak(q, mp, 0, err);
+ return (err);
}
-/*
- * DLDIOC_GETAUTOPUSH
- */
-static void
-drv_ioc_getap(dld_ctl_str_t *ctls, mblk_t *mp)
+static int
+drv_ioc_getap(datalink_id_t linkid, struct dlautopush *dlap)
{
- dld_ioc_ap_t *diap;
dld_ap_t *dap;
int i, err;
- queue_t *q = ctls->cs_wq;
-
- if ((err = miocpullup(mp, sizeof (dld_ioc_ap_t))) != 0)
- goto failed;
-
- diap = (dld_ioc_ap_t *)mp->b_cont->b_rptr;
rw_enter(&dld_ap_hash_lock, RW_READER);
if (mod_hash_find(dld_ap_hashp,
- (mod_hash_key_t)(uintptr_t)diap->dia_linkid,
+ (mod_hash_key_t)(uintptr_t)linkid,
(mod_hash_val_t *)&dap) != 0) {
err = ENOENT;
rw_exit(&dld_ap_hash_lock);
@@ -822,54 +837,38 @@ drv_ioc_getap(dld_ctl_str_t *ctls, mblk_t *mp)
/*
* Retrieve the configuration.
*/
- diap->dia_anchor = dap->da_anchor;
- diap->dia_npush = dap->da_npush;
+ dlap->dap_anchor = dap->da_anchor;
+ dlap->dap_npush = dap->da_npush;
for (i = 0; i < dap->da_npush; i++) {
- (void) strlcpy(diap->dia_aplist[i], dap->da_aplist[i],
+ (void) strlcpy(dlap->dap_aplist[i], dap->da_aplist[i],
FMNAMESZ + 1);
}
rw_exit(&dld_ap_hash_lock);
- miocack(q, mp, sizeof (dld_ioc_ap_t), 0);
- return;
+ return (0);
failed:
- miocnak(q, mp, 0, err);
+ return (err);
}
-/*
- * DLDIOC_CLRAUTOPUSH
- */
-static void
-drv_ioc_clrap(dld_ctl_str_t *ctls, mblk_t *mp)
+static int
+drv_ioc_clrap(datalink_id_t linkid)
{
- dld_ioc_ap_t *diap;
mod_hash_val_t val;
mod_hash_key_t key;
- int err;
- queue_t *q = ctls->cs_wq;
- if ((err = miocpullup(mp, sizeof (dld_ioc_ap_t))) != 0)
- goto done;
-
- diap = (dld_ioc_ap_t *)mp->b_cont->b_rptr;
- key = (mod_hash_key_t)(uintptr_t)diap->dia_linkid;
+ key = (mod_hash_key_t)(uintptr_t)linkid;
rw_enter(&dld_ap_hash_lock, RW_WRITER);
if (mod_hash_find(dld_ap_hashp, key, &val) != 0) {
rw_exit(&dld_ap_hash_lock);
- goto done;
+ return (0);
}
VERIFY(mod_hash_remove(dld_ap_hashp, key, &val) == 0);
kmem_free(val, sizeof (dld_ap_t));
rw_exit(&dld_ap_hash_lock);
-
-done:
- if (err == 0)
- miocack(q, mp, 0, 0);
- else
- miocnak(q, mp, 0, err);
+ return (0);
}
/*
@@ -896,52 +895,6 @@ done:
}
/*
- * DLDIOC_SETZID
- */
-static void
-drv_ioc_setzid(dld_ctl_str_t *ctls, mblk_t *mp)
-{
- queue_t *q = ctls->cs_wq;
- dld_ioc_setzid_t *dis;
- int err;
-
- if ((err = miocpullup(mp, sizeof (dld_ioc_setzid_t))) != 0)
- goto done;
-
- dis = (dld_ioc_setzid_t *)mp->b_cont->b_rptr;
- err = dls_devnet_setzid(dis->dis_link, dis->dis_zid);
-
-done:
- if (err == 0)
- miocack(q, mp, 0, 0);
- else
- miocnak(q, mp, 0, err);
-}
-
-/*
- * DLDIOC_GETZID
- */
-static void
-drv_ioc_getzid(dld_ctl_str_t *ctls, mblk_t *mp)
-{
- queue_t *q = ctls->cs_wq;
- dld_ioc_getzid_t *dig;
- int err;
-
- if ((err = miocpullup(mp, sizeof (dld_ioc_getzid_t))) != 0)
- goto done;
-
- dig = (dld_ioc_getzid_t *)mp->b_cont->b_rptr;
- err = dls_devnet_getzid(dig->dig_linkid, &dig->dig_zid);
-
-done:
- if (err == 0)
- miocack(q, mp, sizeof (dld_ioc_getzid_t), 0);
- else
- miocnak(q, mp, 0, err);
-}
-
-/*
* Process an IOCTL message received by the control node.
*/
static void
@@ -981,24 +934,9 @@ drv_ioc(dld_ctl_str_t *ctls, mblk_t *mp)
case DLDIOC_VLAN_ATTR:
drv_ioc_vlan_attr(ctls, mp);
return;
- case DLDIOC_SETAUTOPUSH:
- drv_ioc_setap(ctls, mp);
- return;
- case DLDIOC_GETAUTOPUSH:
- drv_ioc_getap(ctls, mp);
- return;
- case DLDIOC_CLRAUTOPUSH:
- drv_ioc_clrap(ctls, mp);
- return;
case DLDIOC_DOORSERVER:
drv_ioc_doorserver(ctls, mp);
return;
- case DLDIOC_SETZID:
- drv_ioc_setzid(ctls, mp);
- return;
- case DLDIOC_GETZID:
- drv_ioc_getzid(ctls, mp);
- return;
case DLDIOC_RENAME:
drv_ioc_rename(ctls, mp);
return;
diff --git a/usr/src/uts/common/sys/dld.h b/usr/src/uts/common/sys/dld.h
index b6178707f3..1af906c90b 100644
--- a/usr/src/uts/common/sys/dld.h
+++ b/usr/src/uts/common/sys/dld.h
@@ -26,8 +26,6 @@
#ifndef _SYS_DLD_H
#define _SYS_DLD_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Data-Link Driver (public header).
*/
@@ -178,15 +176,13 @@ typedef struct dld_ioc_delete_vlan {
datalink_id_t did_linkid;
} dld_ioc_delete_vlan_t;
-#define DLDIOC_SETAUTOPUSH (DLDIOC | 0x0d)
-#define DLDIOC_GETAUTOPUSH (DLDIOC | 0x0e)
-#define DLDIOC_CLRAUTOPUSH (DLDIOC | 0x0f)
-typedef struct dld_ioc_ap {
- datalink_id_t dia_linkid;
- uint_t dia_anchor;
- uint_t dia_npush;
- char dia_aplist[MAXAPUSH][FMNAMESZ+1];
-} dld_ioc_ap_t;
+/*
+ * The following constants have been removed, and the slots are open:
+ *
+ * #define DLDIOC_SETAUTOPUSH (DLDIOC | 0x0d)
+ * #define DLDIOC_GETAUTOPUSH (DLDIOC | 0x0e)
+ * #define DLDIOC_CLRAUTOPUSH (DLDIOC | 0x0f)
+ */
#define DLDIOC_DOORSERVER (DLDIOC | 0x10)
typedef struct dld_ioc_door {
@@ -201,21 +197,17 @@ typedef struct dld_ioc_rename {
} dld_ioc_rename_t;
/*
- * DLDIOC_SETZID sets the zoneid of a given link. It could cause a VLAN to be
- * implicitly created. Note that we will hold a reference for the given link
- * whenever it has a zoneid other than the global zone.
+ * The following constants have been removed, and the slots are open:
+ *
+ * #define DLDIOC_SETZID (DLDIOC | 0x12)
+ * #define DLDIOC_GETZID (DLDIOC | 0x13)
*/
-#define DLDIOC_SETZID (DLDIOC | 0x12)
-typedef struct dld_ioc_setzid {
- char dis_link[MAXLINKNAMELEN];
- zoneid_t dis_zid;
-} dld_ioc_setzid_t;
-
-#define DLDIOC_GETZID (DLDIOC | 0x13)
-typedef struct dld_ioc_getzid {
- datalink_id_t dig_linkid;
- zoneid_t dig_zid;
-} dld_ioc_getzid_t;
+
+typedef struct dld_ioc_zid {
+ zoneid_t diz_zid;
+ char diz_link[MAXLINKNAMELEN];
+ boolean_t diz_is_ppa_hack;
+} dld_ioc_zid_t;
/*
* data-link autopush configuration.
diff --git a/usr/src/uts/common/sys/mac.h b/usr/src/uts/common/sys/mac.h
index e314da779f..bc930dfce2 100644
--- a/usr/src/uts/common/sys/mac.h
+++ b/usr/src/uts/common/sys/mac.h
@@ -26,8 +26,6 @@
#ifndef _SYS_MAC_H
#define _SYS_MAC_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
@@ -116,6 +114,8 @@ typedef enum {
MAC_PROP_AUTONEG,
MAC_PROP_EN_AUTONEG,
MAC_PROP_MTU,
+ MAC_PROP_ZONE,
+ MAC_PROP_AUTOPUSH,
MAC_PROP_FLOWCTRL,
MAC_PROP_ADV_1000FDX_CAP,
MAC_PROP_EN_1000FDX_CAP,