diff options
author | Aruna Ramakrishna - Sun Microsystems <Aruna.Ramakrishna@Sun.COM> | 2008-08-15 14:27:06 -0400 |
---|---|---|
committer | Aruna Ramakrishna - Sun Microsystems <Aruna.Ramakrishna@Sun.COM> | 2008-08-15 14:27:06 -0400 |
commit | 3bc21d0a9c7b31b1132c254e389a4114c23bcf00 (patch) | |
tree | daf267db046835b41826cd114140ca0503b4bbcc | |
parent | 43afaaa8b73f73af765f4fa90f39a0f86cb8a364 (diff) | |
download | illumos-joyent-3bc21d0a9c7b31b1132c254e389a4114c23bcf00.tar.gz |
6714745 zone/autopush should be implemented using DLDIOC_*MACPROP ioctls.
-rw-r--r-- | usr/src/cmd/truss/codes.c | 11 | ||||
-rw-r--r-- | usr/src/cmd/zoneadmd/vplat.c | 95 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/libdllink.c | 105 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/libdllink.h | 5 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/linkprop.c | 420 | ||||
-rw-r--r-- | usr/src/lib/libdladm/common/mapfile-vers | 3 | ||||
-rw-r--r-- | usr/src/uts/common/io/dld/dld_drv.c | 190 | ||||
-rw-r--r-- | usr/src/uts/common/sys/dld.h | 42 | ||||
-rw-r--r-- | usr/src/uts/common/sys/mac.h | 4 |
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, |