diff options
author | Sebastien Roy <Sebastien.Roy@Sun.COM> | 2008-08-26 19:16:34 -0400 |
---|---|---|
committer | Sebastien Roy <Sebastien.Roy@Sun.COM> | 2008-08-26 19:16:34 -0400 |
commit | eae72b5b807baa9116e64502cbb278edf15f3146 (patch) | |
tree | fc7a46e5b44edce207501bd6c3de33b94bc7d435 /usr/src | |
parent | 68ce0b7d91cfc03d5ad6ba0de356c08a168971e6 (diff) | |
download | illumos-joyent-eae72b5b807baa9116e64502cbb278edf15f3146.tar.gz |
PSARC 2008/473 Fine-Grained Privileges for Datalink Administration
6695904 least privileges for datalink actions
6729477 pcwl accidentally requires privileges for WLAN_GET_PARAM ioctl
6679049 ucred_t leak in dlmgmtd
6738245 dld's _init() doesn't teardown if mod_install() fails
6738987 i.devpolicy pattern matching accidentally matches random lines
Diffstat (limited to 'usr/src')
41 files changed, 936 insertions, 1459 deletions
diff --git a/usr/src/cmd/devfsadm/misc_link.c b/usr/src/cmd/devfsadm/misc_link.c index 0cd8ad55ca..df64c8bb96 100644 --- a/usr/src/cmd/devfsadm/misc_link.c +++ b/usr/src/cmd/devfsadm/misc_link.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <regex.h> #include <devfsadm.h> #include <stdio.h> @@ -114,6 +112,9 @@ static devfsadm_create_t misc_cbt[] = { "(^ipsync$)|(^ipscan$)|(^iplookup$)", TYPE_EXACT | DRV_RE, ILEVEL_0, minor_name, }, + { "pseudo", "ddi_pseudo", "dld", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name + }, { "pseudo", "ddi_pseudo", "(^kdmouse$)|(^logi$)|(^rootprop$)|(^msm$)", TYPE_EXACT | DRV_RE, ILEVEL_0, node_name diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c index 87626276cb..f35bf227b6 100644 --- a/usr/src/cmd/dladm/dladm.c +++ b/usr/src/cmd/dladm/dladm.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <ctype.h> #include <locale.h> @@ -852,10 +850,6 @@ main(int argc, char *argv[]) if (argc < 2) usage(); - if (!priv_ineffect(PRIV_SYS_NET_CONFIG) || - !priv_ineffect(PRIV_NET_RAWACCESS)) - die("insufficient privileges"); - for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) { cmdp = &cmds[i]; if (strcmp(argv[1], cmdp->c_name) == 0) { diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_door.c b/usr/src/cmd/dlmgmtd/dlmgmt_door.c index 8e1a1d9cd3..fc50b5c5b1 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_door.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_door.c @@ -997,7 +997,7 @@ dlmgmt_handler(void *cookie, char *argp, size_t argsz, door_desc_t *dp, dlmgmt_door_info_t *infop = NULL; dlmgmt_retval_t retval; void *retvalp; - int err; + int err = 0; int i; for (i = 0; i < DLMGMT_INFO_TABLE_SIZE; i++) { @@ -1023,11 +1023,11 @@ dlmgmt_handler(void *cookie, char *argp, size_t argsz, door_desc_t *dp, } eset = ucred_getprivset(cred, PRIV_EFFECTIVE); - if (eset == NULL || !priv_ismember(eset, PRIV_SYS_NET_CONFIG)) { - ucred_free(cred); + if (eset == NULL || !priv_ismember(eset, PRIV_SYS_DL_CONFIG)) err = EACCES; + ucred_free(cred); + if (err != 0) goto fail; - } } /* diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_main.c b/usr/src/cmd/dlmgmtd/dlmgmt_main.c index 15472f670d..e6d7581138 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_main.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_main.c @@ -45,7 +45,6 @@ #include <signal.h> #include <stdlib.h> #include <stdio.h> -#include <stropts.h> #include <strings.h> #include <syslog.h> #include <sys/dld.h> @@ -71,19 +70,13 @@ static int dlmgmt_set_doorfd(boolean_t start) { dld_ioc_door_t did; - struct strioctl iocb; int err = 0; assert(dld_control_fd != -1); did.did_start_door = start; - iocb.ic_cmd = DLDIOC_DOORSERVER; - iocb.ic_timout = 0; - iocb.ic_len = sizeof (did); - iocb.ic_dp = (char *)&did; - - if (ioctl(dld_control_fd, I_STR, &iocb) == -1) + if (ioctl(dld_control_fd, DLDIOC_DOORSERVER, &did) == -1) err = errno; return (err); @@ -250,10 +243,11 @@ dlmgmt_init_privileges() return (errno); /* - * The PRIV_SYS_CONFIG privilege is needed to post sysevents. + * We need PRIV_SYS_DL_CONFIG for the DLDIOC_DOORSERVER ioctl, + * and PRIV_SYS_CONFIG to post sysevents. */ if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, UID_DLADM, - GID_SYS, PRIV_SYS_NET_CONFIG, PRIV_SYS_CONFIG, NULL) == -1) { + GID_SYS, PRIV_SYS_DL_CONFIG, PRIV_SYS_CONFIG, NULL) == -1) { (void) close(dld_control_fd); dld_control_fd = -1; return (EPERM); diff --git a/usr/src/lib/libdladm/common/libdladm.c b/usr/src/lib/libdladm/common/libdladm.c index e07cc64650..3a3cac49d8 100644 --- a/usr/src/lib/libdladm/common/libdladm.c +++ b/usr/src/lib/libdladm/common/libdladm.c @@ -23,10 +23,7 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <unistd.h> -#include <stropts.h> #include <errno.h> #include <ctype.h> #include <fcntl.h> @@ -40,23 +37,6 @@ static char dladm_rootdir[MAXPATHLEN] = "/"; -/* - * Issue an ioctl to the specified file descriptor attached to the - * DLD control driver interface. - */ -int -i_dladm_ioctl(int fd, int ic_cmd, void *ic_dp, int ic_len) -{ - struct strioctl iocb; - - iocb.ic_cmd = ic_cmd; - iocb.ic_timout = 0; - iocb.ic_len = ic_len; - iocb.ic_dp = (char *)ic_dp; - - return (ioctl(fd, I_STR, &iocb)); -} - const char * dladm_status2str(dladm_status_t status, char *buf) { @@ -181,6 +161,7 @@ dladm_errno2status(int err) case ENETDOWN: return (DLADM_STATUS_NONOTIF); case EACCES: + case EPERM: return (DLADM_STATUS_DENIED); case EIO: return (DLADM_STATUS_IOERR); diff --git a/usr/src/lib/libdladm/common/libdladm_impl.h b/usr/src/lib/libdladm/common/libdladm_impl.h index f71495e5d9..d4a5a52445 100644 --- a/usr/src/lib/libdladm/common/libdladm_impl.h +++ b/usr/src/lib/libdladm/common/libdladm_impl.h @@ -26,8 +26,6 @@ #ifndef _LIBDLADM_IMPL_H #define _LIBDLADM_IMPL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <libdladm.h> #include <stdio.h> @@ -45,7 +43,6 @@ typedef struct val_desc { #define VALCNT(vals) (sizeof ((vals)) / sizeof (val_desc_t)) -extern int i_dladm_ioctl(int, int, void *, int); extern dladm_status_t dladm_errno2status(int); extern dladm_status_t i_dladm_rw_db(const char *, mode_t, dladm_status_t (*)(void *, FILE *, FILE *), diff --git a/usr/src/lib/libdladm/common/libdlaggr.c b/usr/src/lib/libdladm/common/libdlaggr.c index 4c61371247..dba84441ea 100644 --- a/usr/src/lib/libdladm/common/libdlaggr.c +++ b/usr/src/lib/libdladm/common/libdlaggr.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> @@ -51,8 +49,6 @@ * configure link aggregations. */ -#define DLADM_AGGR_DEV "/devices/pseudo/aggr@0:" AGGR_DEVNAME_CTL - /* Limits on buffer size for LAIOC_INFO request */ #define MIN_INFO_SIZE (4*1024) #define MAX_INFO_SIZE (128*1024) @@ -140,14 +136,14 @@ static dladm_aggr_port_state_t port_states[] = { (sizeof (port_states) / sizeof (dladm_aggr_port_state_t)) static int -i_dladm_aggr_strioctl(int cmd, void *ptr, int ilen) +i_dladm_aggr_ioctl(int cmd, void *ptr) { int err, fd; - if ((fd = open(DLADM_AGGR_DEV, O_RDWR)) < 0) + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) return (-1); - err = i_dladm_ioctl(fd, cmd, ptr, ilen); + err = ioctl(fd, cmd, ptr); (void) close(fd); return (err); @@ -213,7 +209,7 @@ static dladm_status_t i_dladm_aggr_info_active(datalink_id_t linkid, dladm_aggr_grp_attr_t *attrp) { laioc_info_t *ioc; - int rc, bufsize; + int bufsize; void *where; dladm_status_t status = DLADM_STATUS_OK; @@ -225,8 +221,8 @@ i_dladm_aggr_info_active(datalink_id_t linkid, dladm_aggr_grp_attr_t *attrp) ioc->li_group_linkid = linkid; tryagain: - rc = i_dladm_aggr_strioctl(LAIOC_INFO, ioc, bufsize); - if (rc != 0) { + ioc->li_bufsize = bufsize; + if (i_dladm_aggr_ioctl(LAIOC_INFO, ioc) != 0) { if (errno == ENOSPC) { /* * The LAIOC_INFO call failed due to a short @@ -549,7 +545,7 @@ destroyconf: for (i = 0; i < nports; i++) ioc_ports[i].lp_linkid = ports[i].lp_linkid; - if (i_dladm_aggr_strioctl(cmd, iocp, len) < 0) + if (i_dladm_aggr_ioctl(cmd, iocp) < 0) status = dladm_errno2status(errno); done: @@ -602,7 +598,7 @@ i_dladm_aggr_modify_sys(datalink_id_t linkid, uint32_t mask, ioc.lu_lacp_mode = attr->ld_lacp_mode; ioc.lu_lacp_timer = attr->ld_lacp_timer; - if (i_dladm_aggr_strioctl(LAIOC_MODIFY, &ioc, sizeof (ioc)) < 0) { + if (i_dladm_aggr_ioctl(LAIOC_MODIFY, &ioc) < 0) { if (errno == EINVAL) return (DLADM_STATUS_MACADDRINVAL); else @@ -621,7 +617,7 @@ i_dladm_aggr_create_sys(datalink_id_t linkid, uint16_t key, uint32_t nports, boolean_t mac_addr_fixed, const uchar_t *mac_addr, aggr_lacp_mode_t lacp_mode, aggr_lacp_timer_t lacp_timer, boolean_t force) { - int i, rc, len; + int i, len; laioc_create_t *iocp = NULL; laioc_port_t *ioc_ports; dladm_status_t status = DLADM_STATUS_OK; @@ -651,8 +647,7 @@ i_dladm_aggr_create_sys(datalink_id_t linkid, uint16_t key, uint32_t nports, bcopy(mac_addr, iocp->lc_mac, ETHERADDRL); iocp->lc_mac_fixed = mac_addr_fixed; - rc = i_dladm_aggr_strioctl(LAIOC_CREATE, iocp, len); - if (rc < 0) + if (i_dladm_aggr_ioctl(LAIOC_CREATE, iocp) < 0) status = dladm_errno2status(errno); done: @@ -726,7 +721,7 @@ i_dladm_aggr_up(datalink_id_t linkid, void *arg) if ((status = dladm_up_datalink_id(linkid)) != DLADM_STATUS_OK) { laioc_delete_t ioc; ioc.ld_linkid = linkid; - (void) i_dladm_aggr_strioctl(LAIOC_DELETE, &ioc, sizeof (ioc)); + (void) i_dladm_aggr_ioctl(LAIOC_DELETE, &ioc); goto done; } @@ -1361,8 +1356,7 @@ dladm_aggr_delete(datalink_id_t linkid, uint32_t flags) if (flags & DLADM_OPT_ACTIVE) { ioc.ld_linkid = linkid; - if ((i_dladm_aggr_strioctl(LAIOC_DELETE, &ioc, - sizeof (ioc)) < 0) && + if ((i_dladm_aggr_ioctl(LAIOC_DELETE, &ioc) < 0) && ((errno != ENOENT) || !(flags & DLADM_OPT_PERSIST))) { status = dladm_errno2status(errno); return (status); diff --git a/usr/src/lib/libdladm/common/libdllink.c b/usr/src/lib/libdladm/common/libdllink.c index b9179736c2..8deed6fe76 100644 --- a/usr/src/lib/libdladm/common/libdllink.c +++ b/usr/src/lib/libdladm/common/libdllink.c @@ -54,7 +54,7 @@ i_dladm_info(int fd, const datalink_id_t linkid, dladm_attr_t *dap) dia.dia_linkid = linkid; - if (i_dladm_ioctl(fd, DLDIOC_ATTR, &dia, sizeof (dia)) < 0) + if (ioctl(fd, DLDIOC_ATTR, &dia) < 0) return (dladm_errno2status(errno)); dap->da_max_sdu = dia.dia_max_sdu; @@ -358,7 +358,7 @@ i_dladm_rename_link_c1(datalink_id_t linkid1, const char *link1, if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) return (dladm_errno2status(errno)); - if (i_dladm_ioctl(fd, DLDIOC_RENAME, &dir, sizeof (dir)) < 0) { + if (ioctl(fd, DLDIOC_RENAME, &dir) < 0) { status = dladm_errno2status(errno); (void) close(fd); return (status); @@ -381,8 +381,7 @@ done: if (flags & DLADM_OPT_ACTIVE) { if (status != DLADM_STATUS_OK) { (void) strlcpy(dir.dir_link, link1, MAXLINKNAMELEN); - (void) i_dladm_ioctl(fd, DLDIOC_RENAME, &dir, - sizeof (dir)); + (void) ioctl(fd, DLDIOC_RENAME, &dir); } (void) close(fd); } @@ -483,7 +482,7 @@ i_dladm_rename_link_c2(datalink_id_t linkid1, datalink_id_t linkid2) dir.dir_linkid1 = linkid1; dir.dir_linkid2 = linkid2; - if (i_dladm_ioctl(fd, DLDIOC_RENAME, &dir, sizeof (dir)) < 0) + if (ioctl(fd, DLDIOC_RENAME, &dir) < 0) status = dladm_errno2status(errno); if (status != DLADM_STATUS_OK) { @@ -509,7 +508,7 @@ i_dladm_rename_link_c2(datalink_id_t linkid1, datalink_id_t linkid2) dir.dir_linkid1 = linkid2; dir.dir_linkid2 = linkid1; (void) dladm_init_linkprop(linkid1, B_FALSE); - (void) i_dladm_ioctl(fd, DLDIOC_RENAME, &dir, sizeof (dir)); + (void) ioctl(fd, DLDIOC_RENAME, &dir); (void) close(fd); return (status); } @@ -790,8 +789,7 @@ dladm_phys_info(datalink_id_t linkid, dladm_phys_attr_t *dpap, uint32_t flags) return (dladm_errno2status(errno)); dip.dip_linkid = linkid; - if (i_dladm_ioctl(fd, DLDIOC_PHYS_ATTR, &dip, sizeof (dip)) - < 0) { + if (ioctl(fd, DLDIOC_PHYS_ATTR, &dip) < 0) { status = dladm_errno2status(errno); (void) close(fd); return (status); diff --git a/usr/src/lib/libdladm/common/libdlvlan.c b/usr/src/lib/libdladm/common/libdlvlan.c index d2a78d4f08..f6d855db72 100644 --- a/usr/src/lib/libdladm/common/libdlvlan.c +++ b/usr/src/lib/libdladm/common/libdlvlan.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -58,7 +56,7 @@ i_dladm_vlan_info_active(datalink_id_t vlanid, dladm_vlan_attr_t *dvap) div.div_vlanid = vlanid; - if (i_dladm_ioctl(fd, DLDIOC_VLAN_ATTR, &div, sizeof (div)) < 0) + if (ioctl(fd, DLDIOC_VLAN_ATTR, &div) < 0) status = dladm_errno2status(errno); dvap->dv_vid = div.div_vid; @@ -193,8 +191,7 @@ dladm_vlan_create(const char *vlan, datalink_id_t linkid, uint16_t vid, dic.dic_vid = vid; dic.dic_force = (flags & DLADM_OPT_FORCE) != 0; - if (i_dladm_ioctl(fd, DLDIOC_CREATE_VLAN, &dic, - sizeof (dic)) < 0) { + if (ioctl(fd, DLDIOC_CREATE_VLAN, &dic) < 0) { status = dladm_errno2status(errno); if (flags & DLADM_OPT_PERSIST) (void) dladm_remove_conf(vlanid); @@ -235,8 +232,7 @@ dladm_vlan_delete(datalink_id_t vlanid, uint32_t flags) return (dladm_errno2status(errno)); did.did_linkid = vlanid; - if ((i_dladm_ioctl(fd, DLDIOC_DELETE_VLAN, &did, - sizeof (did)) < 0) && + if ((ioctl(fd, DLDIOC_DELETE_VLAN, &did) < 0) && ((errno != ENOENT) || !(flags & DLADM_OPT_PERSIST))) { (void) close(fd); return (dladm_errno2status(errno)); @@ -300,7 +296,7 @@ i_dladm_vlan_up(datalink_id_t vlanid, void *arg) } dic.dic_vlanid = vlanid; - if (i_dladm_ioctl(fd, DLDIOC_CREATE_VLAN, &dic, sizeof (dic)) < 0) { + if (ioctl(fd, DLDIOC_CREATE_VLAN, &dic) < 0) { status = dladm_errno2status(errno); goto done; } @@ -309,8 +305,7 @@ i_dladm_vlan_up(datalink_id_t vlanid, void *arg) dld_ioc_delete_vlan_t did; did.did_linkid = vlanid; - (void) i_dladm_ioctl(fd, DLDIOC_DELETE_VLAN, &did, - sizeof (did)); + (void) ioctl(fd, DLDIOC_DELETE_VLAN, &did); } else { /* * Reset the active linkprop of this specific link. diff --git a/usr/src/lib/libdladm/common/libdlvnic.c b/usr/src/lib/libdladm/common/libdlvnic.c index 272763b61d..ac97372785 100644 --- a/usr/src/lib/libdladm/common/libdlvnic.c +++ b/usr/src/lib/libdladm/common/libdlvnic.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> @@ -46,8 +44,6 @@ * VNIC administration library. */ -#define VNIC_DEV "/devices/pseudo/vnic@0:" VNIC_CTL_NODE_NAME - /* Limits on buffer size for VNIC_IOC_INFO request */ #define MIN_INFO_SIZE (4*1024) #define MAX_INFO_SIZE (128*1024) @@ -73,7 +69,6 @@ typedef struct dladm_vnic_modify_attr { static dladm_status_t i_dladm_vnic_create_sys(int fd, dladm_vnic_attr_db_t *attr) { - int rc; vnic_ioc_create_t ioc; ioc.vc_vnic_id = attr->vt_vnic_id; @@ -82,9 +77,7 @@ i_dladm_vnic_create_sys(int fd, dladm_vnic_attr_db_t *attr) ioc.vc_mac_len = attr->vt_mac_len; bcopy(attr->vt_mac_addr, ioc.vc_mac_addr, attr->vt_mac_len); - rc = i_dladm_ioctl(fd, VNIC_IOC_CREATE, &ioc, sizeof (ioc)); - - if (rc < 0) + if (ioctl(fd, VNIC_IOC_CREATE, &ioc) < 0) return (dladm_errno2status(errno)); return (DLADM_STATUS_OK); @@ -97,7 +90,7 @@ static dladm_status_t i_dladm_vnic_modify_sys(datalink_id_t vnic_id, uint32_t modify_mask, dladm_vnic_modify_attr_t *attr) { - int rc; + dladm_status_t status = DLADM_STATUS_OK; int fd; vnic_ioc_modify_t ioc; @@ -111,17 +104,14 @@ i_dladm_vnic_modify_sys(datalink_id_t vnic_id, uint32_t modify_mask, ioc.vm_mac_len = attr->vm_mac_len; bcopy(attr->vm_mac_addr, ioc.vm_mac_addr, MAXMACADDRLEN); - if ((fd = open(VNIC_DEV, O_RDWR)) < 0) + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) return (dladm_errno2status(errno)); - rc = i_dladm_ioctl(fd, VNIC_IOC_MODIFY, &ioc, sizeof (ioc)); + if (ioctl(fd, VNIC_IOC_MODIFY, &ioc) < 0) + status = dladm_errno2status(errno); (void) close(fd); - - if (rc < 0) - return (dladm_errno2status(errno)); - - return (DLADM_STATUS_OK); + return (status); } /* @@ -133,14 +123,14 @@ dladm_vnic_info(datalink_id_t vnic_id, dladm_vnic_attr_sys_t *attrp, { vnic_ioc_info_t *ioc; vnic_ioc_info_vnic_t *vnic; - int rc, bufsize, fd; + int bufsize, fd; dladm_status_t status = DLADM_STATUS_OK; /* for now, only temporary creations are supported */ if (flags & DLADM_OPT_PERSIST) return (dladm_errno2status(ENOTSUP)); - if ((fd = open(VNIC_DEV, O_RDWR)) == -1) + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) == -1) return (dladm_errno2status(errno)); bufsize = sizeof (vnic_ioc_info_t) + sizeof (vnic_ioc_info_vnic_t); @@ -151,8 +141,8 @@ dladm_vnic_info(datalink_id_t vnic_id, dladm_vnic_attr_sys_t *attrp, } ioc->vi_vnic_id = vnic_id; - rc = i_dladm_ioctl(fd, VNIC_IOC_INFO, ioc, bufsize); - if (rc != 0) { + ioc->vi_size = bufsize - sizeof (vnic_ioc_info_t); + if (ioctl(fd, VNIC_IOC_INFO, ioc) != 0) { status = dladm_errno2status(errno); goto bail; } @@ -178,13 +168,10 @@ static dladm_status_t i_dladm_vnic_delete_sys(int fd, dladm_vnic_attr_sys_t *attr) { vnic_ioc_delete_t ioc; - int rc; ioc.vd_vnic_id = attr->va_vnic_id; - rc = i_dladm_ioctl(fd, VNIC_IOC_DELETE, &ioc, sizeof (ioc)); - - if (rc < 0) + if (ioctl(fd, VNIC_IOC_DELETE, &ioc) < 0) return (dladm_errno2status(errno)); return (DLADM_STATUS_OK); @@ -283,7 +270,7 @@ dladm_vnic_create(const char *vnic, datalink_id_t linkid, attr.vt_mac_len = mac_len; bcopy(mac_addr, attr.vt_mac_addr, mac_len); - if ((fd = open(VNIC_DEV, O_RDWR)) < 0) { + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { status = dladm_errno2status(errno); goto done; } @@ -342,7 +329,7 @@ dladm_vnic_delete(datalink_id_t vnic_id, uint32_t flags) if (flags & DLADM_OPT_PERSIST) return (dladm_errno2status(ENOTSUP)); - if ((fd = open(VNIC_DEV, O_RDWR)) < 0) + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) return (dladm_errno2status(errno)); sys_attr.va_vnic_id = vnic_id; diff --git a/usr/src/lib/libdladm/common/libdlwlan.c b/usr/src/lib/libdladm/common/libdlwlan.c index ff5c41b989..ee46fca3ee 100644 --- a/usr/src/lib/libdladm/common/libdlwlan.c +++ b/usr/src/lib/libdladm/common/libdlwlan.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <libintl.h> #include <stdio.h> #include <stdlib.h> @@ -816,27 +814,20 @@ done: return (status); } +/* + * Check to see if the link is wireless. + */ static dladm_status_t dladm_wlan_validate(datalink_id_t linkid) { - wldp_t *gbuf; + uint32_t media; dladm_status_t status; - if ((gbuf = malloc(MAX_BUF_LEN)) == NULL) { - status = DLADM_STATUS_NOMEM; - goto done; - } - - /* - * Check to see if the link is wireless. - */ - if ((status = do_get_bsstype(linkid, gbuf)) != DLADM_STATUS_OK) { - status = DLADM_STATUS_LINKINVAL; - goto done; + status = dladm_datalink_id2info(linkid, NULL, NULL, &media, NULL, 0); + if (status == DLADM_STATUS_OK) { + if (media != DL_WIFI) + status = DLADM_STATUS_LINKINVAL; } - -done: - free(gbuf); return (status); } @@ -1084,7 +1075,7 @@ i_dladm_wlan_ioctl(datalink_id_t linkid, wldp_t *gbuf, uint_t id, size_t len, */ (void) snprintf(linkname, MAXPATHLEN, "/dev/net/%s", link); if ((fd = open(linkname, O_RDWR)) < 0) - return (DLADM_STATUS_LINKINVAL); + return (dladm_errno2status(errno)); gbuf->wldp_type = NET_802_11; gbuf->wldp_id = id; diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c index 42851ce54c..2e78907edb 100644 --- a/usr/src/lib/libdladm/common/linkprop.c +++ b/usr/src/lib/libdladm/common/linkprop.c @@ -198,7 +198,7 @@ static dladm_public_prop_t dladm_prop[] = { { MAC_PROP_DUPLEX, sizeof (link_duplex_t), "duplex", "link duplex mode" }, - {MAC_PROP_SPEED, sizeof (uint64_t), + { MAC_PROP_SPEED, sizeof (uint64_t), "speed", "link speed (bps)" }, { MAC_PROP_STATUS, sizeof (link_state_t), @@ -1736,7 +1736,7 @@ 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; - int fd, dsize; + int fd; dladm_status_t status = DLADM_STATUS_OK; uint8_t u8; uint16_t u16; @@ -1778,12 +1778,11 @@ i_dladm_set_public_prop(prop_desc_t *pd, datalink_id_t linkid, 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); goto done; } - if (i_dladm_ioctl(fd, DLDIOC_SETMACPROP, dip, dsize) < 0) + if (ioctl(fd, DLDIOC_SETMACPROP, dip) < 0) status = dladm_errno2status(errno); (void) close(fd); @@ -1796,7 +1795,7 @@ static dld_ioc_macprop_t * i_dladm_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags, dladm_status_t *status) { - int fd, dsize; + int fd; dld_ioc_macprop_t *dip = NULL; *status = DLADM_STATUS_OK; @@ -1805,15 +1804,12 @@ i_dladm_get_public_prop(datalink_id_t linkid, char *prop_name, uint_t flags, if (dip == NULL) return (NULL); - dsize = MAC_PROP_BUFSIZE(dip->pr_valsize); - if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { *status = dladm_errno2status(errno); goto done; } - if (i_dladm_ioctl(fd, DLDIOC_GETMACPROP, dip, dsize) < 0) { + if (ioctl(fd, DLDIOC_GETMACPROP, dip) < 0) *status = dladm_errno2status(errno); - } (void) close(fd); done: @@ -2004,7 +2000,7 @@ 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; + int bufsize = 0; dld_ioc_macprop_t *dip = NULL; uchar_t *dp; dladm_public_prop_t *p; @@ -2038,14 +2034,13 @@ i_dladm_set_prop(datalink_id_t linkid, const char *prop_name, return (status); dp = (uchar_t *)dip->pr_val; - dsize = sizeof (dld_ioc_macprop_t) + bufsize; slen = 0; if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { status = dladm_errno2status(errno); goto done; } if (prop_val == NULL) { - if (i_dladm_ioctl(fd, DLDIOC_GETMACPROP, dip, dsize) < 0) { + if (ioctl(fd, DLDIOC_GETMACPROP, dip) < 0) { status = dladm_errno2status(errno); goto done; } @@ -2064,9 +2059,8 @@ i_dladm_set_prop(datalink_id_t linkid, const char *prop_name, dp += (plen + 1); } } - if (i_dladm_ioctl(fd, DLDIOC_SETMACPROP, dip, dsize) < 0) { + if (ioctl(fd, DLDIOC_SETMACPROP, dip) < 0) status = dladm_errno2status(errno); - } done: if (fd > 0) @@ -2081,7 +2075,6 @@ i_dladm_get_prop(datalink_id_t linkid, const char *prop_name, { int fd; dladm_status_t status = DLADM_STATUS_OK; - uint_t dsize; dld_ioc_macprop_t *dip = NULL; dladm_public_prop_t *p; char tmp = '\0'; @@ -2106,14 +2099,13 @@ i_dladm_get_prop(datalink_id_t linkid, const char *prop_name, dip = i_dladm_buf_alloc(1024, linkid, prop_name, dld_flags, &status); if (dip == NULL) return (status); - dsize = MAC_PROP_BUFSIZE(dip->pr_valsize); if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { free(dip); return (DLADM_STATUS_BADARG); } - if ((status = i_dladm_ioctl(fd, DLDIOC_GETMACPROP, dip, dsize)) < 0) { + if (ioctl(fd, DLDIOC_GETMACPROP, dip) < 0) { status = dladm_errno2status(errno); } else { (void) strncpy(*prop_val, dip->pr_val, DLADM_PROP_VAL_MAX); diff --git a/usr/src/lib/libdladm/common/secobj.c b/usr/src/lib/libdladm/common/secobj.c index 7f17a38e4e..6199f32001 100644 --- a/usr/src/lib/libdladm/common/secobj.c +++ b/usr/src/lib/libdladm/common/secobj.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <unistd.h> #include <stdlib.h> #include <strings.h> @@ -55,6 +53,7 @@ static secobj_class_info_t secobj_class_table[] = { {"wpa", DLD_SECOBJ_CLASS_WPA} }; +#define SECOBJ_MAXBUFSZ 65536 #define NSECOBJCLASS \ (sizeof (secobj_class_table) / sizeof (secobj_class_info_t)) @@ -154,10 +153,8 @@ dladm_set_secobj(const char *obj_name, dladm_secobj_class_t class, if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) return (dladm_errno2status(errno)); - if (i_dladm_ioctl(fd, DLDIOC_SECOBJ_SET, &secobj_set, - sizeof (secobj_set)) < 0) { + if (ioctl(fd, DLDIOC_SECOBJ_SET, &secobj_set) < 0) status = dladm_errno2status(errno); - } (void) close(fd); @@ -198,8 +195,8 @@ dladm_get_secobj(const char *obj_name, dladm_secobj_class_t *classp, if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) return (dladm_errno2status(errno)); - if (i_dladm_ioctl(fd, DLDIOC_SECOBJ_GET, &secobj_get, - sizeof (secobj_get)) < 0) + secobj_get.sg_size = sizeof (secobj_get); + if (ioctl(fd, DLDIOC_SECOBJ_GET, &secobj_get) < 0) status = dladm_errno2status(errno); (void) close(fd); @@ -233,8 +230,7 @@ dladm_unset_secobj(const char *obj_name, uint_t flags) if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) return (dladm_errno2status(errno)); - if (i_dladm_ioctl(fd, DLDIOC_SECOBJ_UNSET, &secobj_unset, - sizeof (secobj_unset)) < 0) + if (ioctl(fd, DLDIOC_SECOBJ_UNSET, &secobj_unset) < 0) status = dladm_errno2status(errno); (void) close(fd); @@ -248,7 +244,6 @@ persist: return (status); } -#define SECOBJ_BUFSZ 65536 dladm_status_t dladm_walk_secobj(void *arg, boolean_t (*func)(void *, const char *), uint_t flags) @@ -257,20 +252,40 @@ dladm_walk_secobj(void *arg, boolean_t (*func)(void *, const char *), dladm_status_t status = DLADM_STATUS_OK; dld_ioc_secobj_get_t *secobj_getp; dld_secobj_t *objp; + size_t secobj_bufsz; if ((flags & DLADM_OPT_PERSIST) != 0) return (i_dladm_walk_secobj_db(arg, func)); - secobj_getp = calloc(1, SECOBJ_BUFSZ); - if (secobj_getp == NULL) - return (DLADM_STATUS_NOMEM); + if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) + return (dladm_errno2status(errno)); - if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { + /* Start with enough room for 10 objects, increase if necessary. */ + secobj_bufsz = sizeof (*secobj_getp) + (10 * sizeof (*objp)); + secobj_getp = calloc(1, secobj_bufsz); + if (secobj_getp == NULL) { status = dladm_errno2status(errno); goto done; } - if (i_dladm_ioctl(fd, DLDIOC_SECOBJ_GET, secobj_getp, - SECOBJ_BUFSZ) < 0) { + +tryagain: + secobj_getp->sg_size = secobj_bufsz; + if (ioctl(fd, DLDIOC_SECOBJ_GET, secobj_getp) < 0) { + if (errno == ENOSPC) { + /* Increase the buffer size and try again. */ + secobj_bufsz *= 2; + if (secobj_bufsz > SECOBJ_MAXBUFSZ) { + status = dladm_errno2status(errno); + goto done; + } + secobj_getp = realloc(secobj_getp, secobj_bufsz); + if (secobj_getp == NULL) { + status = dladm_errno2status(errno); + goto done; + } + bzero(secobj_getp, secobj_bufsz); + goto tryagain; + } status = dladm_errno2status(errno); goto done; } diff --git a/usr/src/lib/libsecdb/exec_attr.txt b/usr/src/lib/libsecdb/exec_attr.txt index b076bde54b..186da4dff7 100644 --- a/usr/src/lib/libsecdb/exec_attr.txt +++ b/usr/src/lib/libsecdb/exec_attr.txt @@ -25,8 +25,6 @@ # # execution attributes for profiles. see exec_attr(4) # -#ident "%Z%%M% %I% %E% SMI" -# # All:suser:cmd:::*: Audit Control:suser:cmd:::/etc/security/bsmconv:uid=0 @@ -187,7 +185,7 @@ Network Management:solaris:cmd:::/sbin/route:privs=sys_ip_config Network Management:solaris:cmd:::/sbin/routeadm:euid=0;\ privs=proc_chroot,proc_owner,sys_ip_config Network Management:solaris:cmd:::/sbin/dladm:euid=dladm;egid=sys;\ - privs=sys_net_config,net_rawaccess,proc_audit + privs=sys_dl_config,net_rawaccess,proc_audit Network Management:suser:cmd:::/usr/bin/netstat:uid=0 Network Management:suser:cmd:::/usr/bin/rup:euid=0 Network Management:suser:cmd:::/usr/bin/ruptime:euid=0 @@ -201,7 +199,7 @@ Network Management:suser:cmd:::/usr/sbin/route:uid=0 Network Management:suser:cmd:::/usr/sbin/snoop:uid=0 Network Management:suser:cmd:::/usr/sbin/spray:euid=0 Network Link Security:solaris:cmd:::/sbin/dladm:euid=dladm;egid=sys;\ - privs=sys_net_config,net_rawaccess,proc_audit + privs=sys_dl_config,net_rawaccess,proc_audit Network IPsec Management:solaris:cmd:::/usr/lib/inet/certdb:euid=0;privs=none Network IPsec Management:solaris:cmd:::/usr/lib/inet/certlocal:euid=0;privs=none Network IPsec Management:solaris:cmd:::/usr/lib/inet/certrldb:euid=0;privs=none diff --git a/usr/src/pkgdefs/SUNWcsd/postinstall b/usr/src/pkgdefs/SUNWcsd/postinstall index 877f76bc10..b481a763ca 100644 --- a/usr/src/pkgdefs/SUNWcsd/postinstall +++ b/usr/src/pkgdefs/SUNWcsd/postinstall @@ -20,10 +20,9 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#pragma ident "%Z%%M% %I% %E% SMI" PATH="/usr/bin:/usr/sbin:$PATH"; export PATH @@ -48,6 +47,7 @@ PATH="/usr/bin:/usr/sbin:$PATH"; export PATH prototype_com=' devices/pseudo/arp@0:arp dev/arp devices/pseudo/clone@0:ibd dev/ibd +devices/pseudo/dld@0:ctl dev/dld devices/pseudo/icmp@0:icmp dev/icmp devices/pseudo/icmp@0:icmp dev/rawip devices/pseudo/icmp6@0:icmp6 dev/icmp6 diff --git a/usr/src/pkgdefs/common_files/i.devpolicy b/usr/src/pkgdefs/common_files/i.devpolicy index cdba4b66ae..49a2d25162 100644 --- a/usr/src/pkgdefs/common_files/i.devpolicy +++ b/usr/src/pkgdefs/common_files/i.devpolicy @@ -20,9 +20,7 @@ # CDDL HEADER END # # -# ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # NOTE: When a change is made to the source file for @@ -52,34 +50,34 @@ do rm -f $dest.$$ # potential additions - additions="aggr aggr:ctl bge dld:ctl dnet keysock ibd icmp icmp6 ipsecah ipsecesp openeepr random spdsock vni ipf pfil scsi_vhci" + additions="aggr bge dnet keysock ibd icmp icmp6 ipsecah ipsecesp openeepr random spdsock vni ipf pfil scsi_vhci" for dev in $additions do # if an entry for this driver exists in the source # file... - grep "$dev[ ]" $src > /dev/null 2>&1 + grep "^$dev[ ]" $src > /dev/null 2>&1 if [ $? = 0 ] ; then # ...and no entry exists in the destination # file... - grep "$dev[ ]" $dest > /dev/null 2>&1 + grep "^$dev[ ]" $dest > /dev/null 2>&1 if [ $? != 0 ] ; then # ...then add the entry from # the source file to the # destination file. - grep "$dev[ ]" $src >> $dest + grep "^$dev[ ]" $src >> $dest fi fi done # potential deletions - deletions="elx dld le" + deletions="elx dld dld:ctl aggr:ctl vnic:ctl le" for dev in $deletions do # if an entry for this driver exists in the destination # file... - grep "$dev[ ]" $dest > /dev/null 2>&1 + grep "^$dev[ ]" $dest > /dev/null 2>&1 if [ $? = 0 ] ; then # ...and no entry exists in the source # file... @@ -88,7 +86,7 @@ do # ...then remove the entry from # the destination file. cp $dest $dest.$$ - grep -v "$dev[ ]" $dest.$$ > $dest + grep -v "^$dev[ ]" $dest.$$ > $dest rm -f $dest.$$ fi fi diff --git a/usr/src/pkgdefs/etc/exception_list_i386 b/usr/src/pkgdefs/etc/exception_list_i386 index db64100062..222064ce14 100644 --- a/usr/src/pkgdefs/etc/exception_list_i386 +++ b/usr/src/pkgdefs/etc/exception_list_i386 @@ -84,6 +84,7 @@ usr/include/sys/aggr.h i386 usr/include/sys/aggr_impl.h i386 usr/include/sys/dld.h i386 usr/include/sys/dld_impl.h i386 +usr/include/sys/dld_ioc.h i386 usr/include/sys/dls.h i386 usr/include/sys/dls_impl.h i386 usr/include/sys/mac.h i386 diff --git a/usr/src/pkgdefs/etc/exception_list_sparc b/usr/src/pkgdefs/etc/exception_list_sparc index cc902429c5..55a8cfa2ac 100644 --- a/usr/src/pkgdefs/etc/exception_list_sparc +++ b/usr/src/pkgdefs/etc/exception_list_sparc @@ -73,6 +73,7 @@ usr/include/sys/aggr.h sparc usr/include/sys/aggr_impl.h sparc usr/include/sys/dld.h sparc usr/include/sys/dld_impl.h sparc +usr/include/sys/dld_ioc.h sparc usr/include/sys/dls.h sparc usr/include/sys/dls_impl.h sparc usr/include/sys/mac.h sparc diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh index 842b9c8c2f..76ae09d35a 100644 --- a/usr/src/tools/scripts/bfu.sh +++ b/usr/src/tools/scripts/bfu.sh @@ -24,8 +24,6 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# # Upgrade a machine from a cpio archive area in about 5 minutes. # By Roger Faulkner and Jeff Bonwick, April 1993. # (bfu == Bonwick/Faulkner Upgrade, a.k.a. Blindingly Fast Upgrade) @@ -7955,6 +7953,11 @@ mondo_loop() { rm -rf $rootprefix/etc/dladm fi fi + + # The global zone needs to have its /dev/dld symlink created + # during install so that processes can access it early in boot + # before devfsadm is run. + ln -s ../devices/pseudo/dld@0:ctl $rootprefix/dev/dld fi # Fix up audit permissions @@ -8102,3 +8105,7 @@ print LD_NOAUXFLTR=1 LD_LIBRARY_PATH=/tmp/bfulib $ldlib64 PATH=/tmp/bfubin \ /tmp/bfubin/ksh exit 0 + \ + /tmp/bfubin/ksh + +exit 0 diff --git a/usr/src/uts/common/io/aggr/aggr_ctl.c b/usr/src/uts/common/io/aggr/aggr_ctl.c index 7c5e97c1b0..0cfb177ed6 100644 --- a/usr/src/uts/common/io/aggr/aggr_ctl.c +++ b/usr/src/uts/common/io/aggr/aggr_ctl.c @@ -23,158 +23,116 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * IEEE 802.3ad Link Aggregation -- IOCTL processing. */ -#include <sys/ddi.h> #include <sys/aggr.h> #include <sys/aggr_impl.h> -#include <sys/strsun.h> - -static int aggr_ioc_create(mblk_t *, int); -static int aggr_ioc_delete(mblk_t *, int); -static int aggr_ioc_info(mblk_t *, int); -static int aggr_ioc_add(mblk_t *, int); -static int aggr_ioc_remove(mblk_t *, int); -static int aggr_ioc_modify(mblk_t *, int); - -typedef struct ioc_cmd_s { - int ic_cmd; - int (*ic_func)(mblk_t *, int); -} ioc_cmd_t; - -static ioc_cmd_t ioc_cmd[] = { - {LAIOC_CREATE, aggr_ioc_create}, - {LAIOC_DELETE, aggr_ioc_delete}, - {LAIOC_INFO, aggr_ioc_info}, - {LAIOC_ADD, aggr_ioc_add}, - {LAIOC_REMOVE, aggr_ioc_remove}, - {LAIOC_MODIFY, aggr_ioc_modify}}; - -#define IOC_CMD_SZ (sizeof (ioc_cmd) / sizeof (ioc_cmd_t)) /* * Process a LAIOC_MODIFY request. */ +/* ARGSUSED */ static int -aggr_ioc_modify(mblk_t *mp, int mode) +aggr_ioc_modify(void *karg, intptr_t arg, int mode, cred_t *cred) { - STRUCT_HANDLE(laioc_modify, modify_arg); + laioc_modify_t *modify_arg = karg; uint32_t policy; boolean_t mac_fixed; uchar_t mac_addr[ETHERADDRL]; uint8_t modify_mask_arg, modify_mask = 0; - datalink_id_t linkid; - uint32_t rc; aggr_lacp_mode_t lacp_mode; aggr_lacp_timer_t lacp_timer; - STRUCT_SET_HANDLE(modify_arg, mode, (void *)mp->b_cont->b_rptr); - if (MBLKL(mp->b_cont) < STRUCT_SIZE(modify_arg)) - return (EINVAL); - - linkid = STRUCT_FGET(modify_arg, lu_linkid); - modify_mask_arg = STRUCT_FGET(modify_arg, lu_modify_mask); + modify_mask_arg = modify_arg->lu_modify_mask; if (modify_mask_arg & LAIOC_MODIFY_POLICY) { modify_mask |= AGGR_MODIFY_POLICY; - policy = STRUCT_FGET(modify_arg, lu_policy); + policy = modify_arg->lu_policy; } if (modify_mask_arg & LAIOC_MODIFY_MAC) { modify_mask |= AGGR_MODIFY_MAC; - bcopy(STRUCT_FGET(modify_arg, lu_mac), mac_addr, ETHERADDRL); - mac_fixed = STRUCT_FGET(modify_arg, lu_mac_fixed); + bcopy(modify_arg->lu_mac, mac_addr, ETHERADDRL); + mac_fixed = modify_arg->lu_mac_fixed; } if (modify_mask_arg & LAIOC_MODIFY_LACP_MODE) { modify_mask |= AGGR_MODIFY_LACP_MODE; - lacp_mode = STRUCT_FGET(modify_arg, lu_lacp_mode); + lacp_mode = modify_arg->lu_lacp_mode; } if (modify_mask_arg & LAIOC_MODIFY_LACP_TIMER) { modify_mask |= AGGR_MODIFY_LACP_TIMER; - lacp_timer = STRUCT_FGET(modify_arg, lu_lacp_timer); + lacp_timer = modify_arg->lu_lacp_timer; } - rc = aggr_grp_modify(linkid, NULL, modify_mask, policy, mac_fixed, - mac_addr, lacp_mode, lacp_timer); - - freemsg(mp->b_cont); - mp->b_cont = NULL; - return (rc); + return (aggr_grp_modify(modify_arg->lu_linkid, NULL, modify_mask, + policy, mac_fixed, mac_addr, lacp_mode, lacp_timer)); } /* * Process a LAIOC_CREATE request. */ +/* ARGSUSED */ static int -aggr_ioc_create(mblk_t *mp, int mode) +aggr_ioc_create(void *karg, intptr_t arg, int mode, cred_t *cred) { - STRUCT_HANDLE(laioc_create, create_arg); + laioc_create_t *create_arg = karg; uint16_t nports; laioc_port_t *ports = NULL; + size_t ports_size; uint32_t policy; boolean_t mac_fixed; boolean_t force; uchar_t mac_addr[ETHERADDRL]; aggr_lacp_mode_t lacp_mode; aggr_lacp_timer_t lacp_timer; - int rc, len; - - STRUCT_SET_HANDLE(create_arg, mode, (void *)mp->b_cont->b_rptr); - if ((len = MBLKL(mp->b_cont)) < STRUCT_SIZE(create_arg)) - return (EINVAL); + int rc; - nports = STRUCT_FGET(create_arg, lc_nports); + nports = create_arg->lc_nports; if (nports > AGGR_MAX_PORTS) return (EINVAL); - policy = STRUCT_FGET(create_arg, lc_policy); - lacp_mode = STRUCT_FGET(create_arg, lc_lacp_mode); - lacp_timer = STRUCT_FGET(create_arg, lc_lacp_timer); + policy = create_arg->lc_policy; + lacp_mode = create_arg->lc_lacp_mode; + lacp_timer = create_arg->lc_lacp_timer; - if (len < STRUCT_SIZE(create_arg) + (nports * sizeof (laioc_port_t))) - return (EINVAL); + ports_size = nports * sizeof (laioc_port_t); + ports = kmem_alloc(ports_size, KM_SLEEP); - ports = (laioc_port_t *)(STRUCT_BUF(create_arg) + 1); + if (ddi_copyin((uchar_t *)arg + sizeof (*create_arg), ports, + ports_size, mode) != 0) { + rc = EFAULT; + goto done; + } - bcopy(STRUCT_FGET(create_arg, lc_mac), mac_addr, ETHERADDRL); - mac_fixed = STRUCT_FGET(create_arg, lc_mac_fixed); - force = STRUCT_FGET(create_arg, lc_force); + bcopy(create_arg->lc_mac, mac_addr, ETHERADDRL); + mac_fixed = create_arg->lc_mac_fixed; + force = create_arg->lc_force; - rc = aggr_grp_create(STRUCT_FGET(create_arg, lc_linkid), - STRUCT_FGET(create_arg, lc_key), nports, ports, policy, - mac_fixed, force, mac_addr, lacp_mode, lacp_timer); + rc = aggr_grp_create(create_arg->lc_linkid, create_arg->lc_key, nports, + ports, policy, mac_fixed, force, mac_addr, lacp_mode, lacp_timer); - freemsg(mp->b_cont); - mp->b_cont = NULL; +done: + kmem_free(ports, ports_size); return (rc); } +/* ARGSUSED */ static int -aggr_ioc_delete(mblk_t *mp, int mode) +aggr_ioc_delete(void *karg, intptr_t arg, int mode, cred_t *cred) { - STRUCT_HANDLE(laioc_delete, delete_arg); - int rc; - - STRUCT_SET_HANDLE(delete_arg, mode, (void *)mp->b_cont->b_rptr); - if (STRUCT_SIZE(delete_arg) > MBLKL(mp)) - return (EINVAL); - - rc = aggr_grp_delete(STRUCT_FGET(delete_arg, ld_linkid)); + laioc_delete_t *delete_arg = karg; - freemsg(mp->b_cont); - mp->b_cont = NULL; - return (rc); + return (aggr_grp_delete(delete_arg->ld_linkid)); } typedef struct aggr_ioc_info_state { - uint32_t bytes_left; - uchar_t *where; + uint32_t bytes_left; + uchar_t *where; /* in user buffer */ + int mode; } aggr_ioc_info_state_t; static int @@ -198,7 +156,9 @@ aggr_ioc_info_new_grp(void *arg, datalink_id_t linkid, uint32_t key, grp.lg_lacp_mode = lacp_mode; grp.lg_lacp_timer = lacp_timer; - bcopy(&grp, state->where, sizeof (grp)); + if (ddi_copyout(&grp, state->where, sizeof (grp), state->mode) != 0) + return (EFAULT); + state->where += sizeof (grp); state->bytes_left -= sizeof (grp); @@ -220,7 +180,9 @@ aggr_ioc_info_new_port(void *arg, datalink_id_t linkid, uchar_t *mac, port.lp_state = portstate; port.lp_lacp_state = *lacp_state; - bcopy(&port, state->where, sizeof (port)); + if (ddi_copyout(&port, state->where, sizeof (port), state->mode) != 0) + return (EFAULT); + state->where += sizeof (port); state->bytes_left -= sizeof (port); @@ -229,131 +191,99 @@ aggr_ioc_info_new_port(void *arg, datalink_id_t linkid, uchar_t *mac, /*ARGSUSED*/ static int -aggr_ioc_info(mblk_t *mp, int mode) +aggr_ioc_info(void *karg, intptr_t arg, int mode, cred_t *cred) { - laioc_info_t *info_argp; + laioc_info_t *info_argp = karg; datalink_id_t linkid; - int rc, len; aggr_ioc_info_state_t state; - if ((len = MBLKL(mp->b_cont)) < sizeof (*info_argp)) - return (EINVAL); - - info_argp = (laioc_info_t *)mp->b_cont->b_rptr; - /* * linkid of the group to return. Must not be DATALINK_INVALID_LINKID. */ if ((linkid = info_argp->li_group_linkid) == DATALINK_INVALID_LINKID) return (EINVAL); - state.bytes_left = len - sizeof (laioc_info_t); - state.where = (uchar_t *)(info_argp + 1); + state.bytes_left = info_argp->li_bufsize - sizeof (laioc_info_t); + state.where = (uchar_t *)arg + sizeof (laioc_info_t); + state.mode = mode; - rc = aggr_grp_info(linkid, &state, - aggr_ioc_info_new_grp, aggr_ioc_info_new_port); - - return (rc); + return (aggr_grp_info(linkid, &state, aggr_ioc_info_new_grp, + aggr_ioc_info_new_port)); } static int -aggr_ioc_add(mblk_t *mp, int mode) +aggr_ioc_add_remove(laioc_add_rem_t *add_rem_arg, intptr_t arg, int cmd, + int mode) { - STRUCT_HANDLE(laioc_add_rem, add_arg); - uint32_t nports; + uint16_t nports; laioc_port_t *ports = NULL; - boolean_t force; - int rc, len; - - STRUCT_SET_HANDLE(add_arg, mode, (void *)mp->b_cont->b_rptr); - if ((len = MBLKL(mp->b_cont)) < STRUCT_SIZE(add_arg)) - return (EINVAL); + size_t ports_size; + int rc; - nports = STRUCT_FGET(add_arg, la_nports); + nports = add_rem_arg->la_nports; if (nports > AGGR_MAX_PORTS) return (EINVAL); - if (len < STRUCT_SIZE(add_arg) + (nports * sizeof (laioc_port_t))) - return (EINVAL); - - ports = (laioc_port_t *)(STRUCT_BUF(add_arg) + 1); - force = STRUCT_FGET(add_arg, la_force); + ports_size = nports * sizeof (laioc_port_t); + ports = kmem_alloc(ports_size, KM_SLEEP); + if (ddi_copyin((uchar_t *)arg + sizeof (*add_rem_arg), ports, + ports_size, mode) != 0) { + rc = EFAULT; + goto done; + } - rc = aggr_grp_add_ports(STRUCT_FGET(add_arg, la_linkid), - nports, force, ports); + switch (cmd) { + case LAIOC_ADD: + rc = aggr_grp_add_ports(add_rem_arg->la_linkid, nports, + add_rem_arg->la_force, ports); + break; + case LAIOC_REMOVE: + rc = aggr_grp_rem_ports(add_rem_arg->la_linkid, nports, ports); + break; + } - freemsg(mp->b_cont); - mp->b_cont = NULL; +done: + kmem_free(ports, ports_size); return (rc); } +/* ARGSUSED */ static int -aggr_ioc_remove(mblk_t *mp, int mode) +aggr_ioc_add(void *karg, intptr_t arg, int mode, cred_t *cred) { - STRUCT_HANDLE(laioc_add_rem, rem_arg); - uint32_t nports; - laioc_port_t *ports = NULL; - int rc, len; - - STRUCT_SET_HANDLE(rem_arg, mode, (void *)mp->b_cont->b_rptr); - if ((len = MBLKL(mp->b_cont)) < STRUCT_SIZE(rem_arg)) - return (EINVAL); - - nports = STRUCT_FGET(rem_arg, la_nports); - if (nports > AGGR_MAX_PORTS) - return (EINVAL); - - if (len < STRUCT_SIZE(rem_arg) + (nports * sizeof (laioc_port_t))) - return (EINVAL); - - ports = (laioc_port_t *)(STRUCT_BUF(rem_arg) + 1); + return (aggr_ioc_add_remove(karg, arg, LAIOC_ADD, mode)); +} - rc = aggr_grp_rem_ports(STRUCT_FGET(rem_arg, la_linkid), - nports, ports); +/* ARGSUSED */ +static int +aggr_ioc_remove(void *karg, intptr_t arg, int mode, cred_t *cred) +{ + return (aggr_ioc_add_remove(karg, arg, LAIOC_REMOVE, mode)); +} - freemsg(mp->b_cont); - mp->b_cont = NULL; - return (rc); +static dld_ioc_info_t aggr_ioc_list[] = { + {LAIOC_CREATE, DLDCOPYIN | DLDDLCONFIG, sizeof (laioc_create_t), + aggr_ioc_create}, + {LAIOC_DELETE, DLDCOPYIN | DLDDLCONFIG, sizeof (laioc_delete_t), + aggr_ioc_delete}, + {LAIOC_INFO, DLDCOPYINOUT, sizeof (laioc_info_t), aggr_ioc_info}, + {LAIOC_ADD, DLDCOPYIN | DLDDLCONFIG, sizeof (laioc_add_rem_t), + aggr_ioc_add}, + {LAIOC_REMOVE, DLDCOPYIN | DLDDLCONFIG, sizeof (laioc_add_rem_t), + aggr_ioc_remove}, + {LAIOC_MODIFY, DLDCOPYIN | DLDDLCONFIG, sizeof (laioc_modify_t), + aggr_ioc_modify} +}; + +int +aggr_ioc_init(void) +{ + return (dld_ioc_register(AGGR_IOC, aggr_ioc_list, + DLDIOCCNT(aggr_ioc_list))); } void -aggr_ioctl(queue_t *wq, mblk_t *mp) +aggr_ioc_fini(void) { - struct iocblk *iocp = (struct iocblk *)mp->b_rptr; - int i, err = EINVAL; - mblk_t *nmp; - - if (mp->b_cont == NULL) - goto done; - - /* - * Construct contiguous message - */ - if ((nmp = msgpullup(mp->b_cont, -1)) == NULL) { - err = ENOMEM; - goto done; - } - - freemsg(mp->b_cont); - mp->b_cont = nmp; - - for (i = 0; i < IOC_CMD_SZ; i++) { - if (iocp->ioc_cmd == ioc_cmd[i].ic_cmd) { - err = ioc_cmd[i].ic_func(mp, (int)iocp->ioc_flag); - break; - } - } - - if (err == 0) { - int len = 0; - - if (mp->b_cont != NULL) { - len = MBLKL(mp->b_cont); - } - miocack(wq, mp, len, 0); - return; - } - -done: - miocnak(wq, mp, 0, err); + dld_ioc_unregister(AGGR_IOC); } diff --git a/usr/src/uts/common/io/aggr/aggr_dev.c b/usr/src/uts/common/io/aggr/aggr_dev.c index 2bdd97fc3f..3caf7bdf2c 100644 --- a/usr/src/uts/common/io/aggr/aggr_dev.c +++ b/usr/src/uts/common/io/aggr/aggr_dev.c @@ -23,35 +23,17 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * IEEE 802.3ad Link Aggregation. */ -#include <sys/types.h> -#include <sys/sysmacros.h> #include <sys/conf.h> -#include <sys/cmn_err.h> -#include <sys/list.h> -#include <sys/ksynch.h> -#include <sys/kmem.h> -#include <sys/stream.h> -#include <sys/strsun.h> #include <sys/modctl.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/atomic.h> -#include <sys/stat.h> - -#include <sys/dld_impl.h> #include <sys/aggr.h> #include <sys/aggr_impl.h> -#include <inet/common.h> /* module description */ #define AGGR_LINKINFO "Link Aggregation MAC" -#define AGGR_DRIVER_NAME "aggr" /* device info ptr, only one for instance 0 */ dev_info_t *aggr_dip = NULL; @@ -59,61 +41,39 @@ dev_info_t *aggr_dip = NULL; static int aggr_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); static int aggr_attach(dev_info_t *, ddi_attach_cmd_t); static int aggr_detach(dev_info_t *, ddi_detach_cmd_t); -static int aggr_open(queue_t *, dev_t *, int, int, cred_t *); -static int aggr_close(queue_t *); -static void aggr_wput(queue_t *, mblk_t *); - -/* - * mi_hiwat is set to 1 because of the flow control mechanism implemented - * in dld. refer to the comments in dld_str.c for details. - */ -static struct module_info aggr_module_info = { - 0, - AGGR_DRIVER_NAME, - 0, - INFPSZ, - 1, - 0 -}; - -static struct qinit aggr_r_qinit = { /* read queues */ - NULL, - NULL, - aggr_open, - aggr_close, - NULL, - &aggr_module_info -}; -static struct qinit aggr_w_qinit = { /* write queues */ - (pfi_t)dld_wput, - (pfi_t)dld_wsrv, - NULL, - NULL, - NULL, - &aggr_module_info +static struct cb_ops aggr_cb_ops = { + nulldev, /* open */ + nulldev, /* close */ + nulldev, /* strategy */ + nulldev, /* print */ + nodev, /* dump */ + nodev, /* read */ + nodev, /* write */ + nodev, /* ioctl */ + nodev, /* devmap */ + nodev, /* mmap */ + nodev, /* segmap */ + nochpoll, /* poll */ + ddi_prop_op, /* cb_prop_op */ + 0, /* streamtab */ + D_MP /* Driver compatibility flag */ }; -/* - * Entry points for aggr control node - */ -static struct qinit aggr_w_ctl_qinit = { - (pfi_t)aggr_wput, - NULL, - NULL, - NULL, - NULL, - &aggr_module_info +static struct dev_ops aggr_dev_ops = { + DEVO_REV, /* devo_rev */ + 0, /* refcnt */ + aggr_getinfo, /* get_dev_info */ + nulldev, /* identify */ + nulldev, /* probe */ + aggr_attach, /* attach */ + aggr_detach, /* detach */ + nodev, /* reset */ + &aggr_cb_ops, /* driver operations */ + NULL, /* bus operations */ + nodev /* dev power */ }; -static struct streamtab aggr_streamtab = { - &aggr_r_qinit, - &aggr_w_qinit -}; - -DDI_DEFINE_STREAM_OPS(aggr_dev_ops, nulldev, nulldev, aggr_attach, aggr_detach, - nodev, aggr_getinfo, D_MP, &aggr_streamtab); - static struct modldrv aggr_modldrv = { &mod_driverops, /* Type of module. This one is a driver */ AGGR_LINKINFO, /* short description */ @@ -126,17 +86,25 @@ static struct modlinkage modlinkage = { NULL }; - int _init(void) { - return (mod_install(&modlinkage)); + int err; + + mac_init_ops(&aggr_dev_ops, "aggr"); + if ((err = mod_install(&modlinkage)) != 0) + mac_fini_ops(&aggr_dev_ops); + return (err); } int _fini(void) { - return (mod_remove(&modlinkage)); + int err; + + if ((err = mod_remove(&modlinkage)) == 0) + mac_fini_ops(&aggr_dev_ops); + return (err); } int @@ -145,61 +113,6 @@ _info(struct modinfo *modinfop) return (mod_info(&modlinkage, modinfop)); } -static int -aggr_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp) -{ - if (q->q_ptr != NULL) - return (EBUSY); - - if (getminor(*devp) == AGGR_MINOR_CTL) { - dld_str_t *dsp; - - dsp = dld_str_create(q, DLD_CONTROL, getmajor(*devp), - DL_STYLE1); - if (dsp == NULL) - return (ENOSR); - - /* - * The ioctl handling callback to process control ioctl - * messages; see comments above dld_ioctl() for details. - */ - dsp->ds_ioctl = aggr_ioctl; - - /* - * The aggr control node uses its own set of entry points. - */ - WR(q)->q_qinfo = &aggr_w_ctl_qinit; - *devp = makedevice(getmajor(*devp), dsp->ds_minor); - qprocson(q); - return (0); - } - return (dld_open(q, devp, flag, sflag, credp)); -} - -static int -aggr_close(queue_t *q) -{ - dld_str_t *dsp = q->q_ptr; - - if (dsp->ds_type == DLD_CONTROL) { - qprocsoff(q); - dld_finish_pending_task(dsp); - dsp->ds_ioctl = NULL; - dld_str_destroy(dsp); - return (0); - } - return (dld_close(q)); -} - -static void -aggr_wput(queue_t *q, mblk_t *mp) -{ - if (DB_TYPE(mp) == M_IOCTL) - dld_ioctl(q, mp); - else - freemsg(mp); -} - /*ARGSUSED*/ static int aggr_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, @@ -210,7 +123,7 @@ aggr_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, *result = aggr_dip; return (DDI_SUCCESS); case DDI_INFO_DEVT2INSTANCE: - *result = NULL; + *result = 0; return (DDI_SUCCESS); } return (DDI_FAILURE); @@ -225,13 +138,8 @@ aggr_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) /* we only allow instance 0 to attach */ return (DDI_FAILURE); } - - /* create minor node for control interface */ - if (ddi_create_minor_node(dip, AGGR_DEVNAME_CTL, S_IFCHR, - AGGR_MINOR_CTL, DDI_PSEUDO, 0) != DDI_SUCCESS) { + if (aggr_ioc_init() != 0) return (DDI_FAILURE); - } - aggr_dip = dip; aggr_port_init(); aggr_grp_init(); @@ -256,10 +164,10 @@ aggr_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) return (DDI_FAILURE); aggr_dip = NULL; - ddi_remove_minor_node(dip, AGGR_DEVNAME_CTL); aggr_port_fini(); aggr_grp_fini(); aggr_lacp_fini(); + aggr_ioc_fini(); return (DDI_SUCCESS); case DDI_SUSPEND: diff --git a/usr/src/uts/common/io/dld/dld_drv.c b/usr/src/uts/common/io/dld/dld_drv.c index 0ab4c8ee14..dc32d6604e 100644 --- a/usr/src/uts/common/io/dld/dld_drv.c +++ b/usr/src/uts/common/io/dld/dld_drv.c @@ -31,23 +31,15 @@ #include <sys/mkdev.h> #include <sys/modctl.h> #include <sys/stat.h> -#include <sys/strsun.h> #include <sys/vlan.h> #include <sys/mac.h> #include <sys/dld_impl.h> #include <sys/dls_impl.h> #include <sys/softmac.h> #include <sys/vlan.h> +#include <sys/policy.h> #include <inet/common.h> -/* - * dld control node state, one per open control node session. - */ -typedef struct dld_ctl_str_s { - minor_t cs_minor; - queue_t *cs_wq; -} dld_ctl_str_t; - static void drv_init(void); static int drv_fini(void); @@ -64,77 +56,61 @@ static kmem_cache_t *drv_secobj_cachep; static mod_hash_t *drv_secobj_hash; static void drv_secobj_init(void); 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 * operations only. The entry points exported to mac drivers are defined * in dld_str.c. Refer to the comment on top of dld_str.c for details. */ -static int drv_open(queue_t *, dev_t *, int, int, cred_t *); -static int drv_close(queue_t *); - -static void drv_uw_put(queue_t *, mblk_t *); -static void drv_uw_srv(queue_t *); +static int drv_open(dev_t *, int, int, cred_t *); +static int drv_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); -dev_info_t *dld_dip; /* dev_info_t for the driver */ -uint32_t dld_opt = 0; /* Global options */ -static vmem_t *dld_ctl_vmem; /* for control minor numbers */ +static dev_info_t *dld_dip; /* dev_info_t for the driver */ +uint32_t dld_opt = 0; /* Global options */ #define NAUTOPUSH 32 static mod_hash_t *dld_ap_hashp; static krwlock_t dld_ap_hash_lock; -static struct module_info drv_info = { - 0, /* mi_idnum */ - DLD_DRIVER_NAME, /* mi_idname */ - 0, /* mi_minpsz */ - (64 * 1024), /* mi_maxpsz */ - 1, /* mi_hiwat */ - 0 /* mi_lowat */ -}; - -static struct qinit drv_ur_init = { - NULL, /* qi_putp */ - NULL, /* qi_srvp */ - drv_open, /* qi_qopen */ - drv_close, /* qi_qclose */ - NULL, /* qi_qadmin */ - &drv_info, /* qi_minfo */ - NULL /* qi_mstat */ -}; - -static struct qinit drv_uw_init = { - (pfi_t)drv_uw_put, /* qi_putp */ - (pfi_t)drv_uw_srv, /* qi_srvp */ - NULL, /* qi_qopen */ - NULL, /* qi_qclose */ - NULL, /* qi_qadmin */ - &drv_info, /* qi_minfo */ - NULL /* qi_mstat */ +static struct cb_ops drv_cb_ops = { + drv_open, /* open */ + nulldev, /* close */ + nulldev, /* strategy */ + nulldev, /* print */ + nodev, /* dump */ + nodev, /* read */ + nodev, /* write */ + drv_ioctl, /* ioctl */ + nodev, /* devmap */ + nodev, /* mmap */ + nodev, /* segmap */ + nochpoll, /* poll */ + ddi_prop_op, /* cb_prop_op */ + 0, /* streamtab */ + D_MP /* Driver compatibility flag */ }; -static struct streamtab drv_stream = { - &drv_ur_init, /* st_rdinit */ - &drv_uw_init, /* st_wrinit */ - NULL, /* st_muxrinit */ - NULL /* st_muxwinit */ +static struct dev_ops drv_ops = { + DEVO_REV, /* devo_rev */ + 0, /* refcnt */ + drv_getinfo, /* get_dev_info */ + nulldev, /* identify */ + nulldev, /* probe */ + drv_attach, /* attach */ + drv_detach, /* detach */ + nodev, /* reset */ + &drv_cb_ops, /* driver operations */ + NULL, /* bus operations */ + nodev /* dev power */ }; -DDI_DEFINE_STREAM_OPS(drv_ops, nulldev, nulldev, drv_attach, drv_detach, - nodev, drv_getinfo, D_MP, &drv_stream); - /* * Module linkage information for the kernel. */ - -extern struct mod_ops mod_driverops; - static struct modldrv drv_modldrv = { &mod_driverops, DLD_INFO, @@ -150,30 +126,13 @@ static struct modlinkage drv_modlinkage = { int _init(void) { - int err; - - drv_init(); - - if ((err = mod_install(&drv_modlinkage)) != 0) - return (err); - - return (0); + return (mod_install(&drv_modlinkage)); } int _fini(void) { - int err; - - if ((err = mod_remove(&drv_modlinkage)) != 0) - return (err); - - if (drv_fini() != 0) { - (void) mod_install(&drv_modlinkage); - return (DDI_FAILURE); - } - - return (err); + return (mod_remove(&drv_modlinkage)); } int @@ -188,8 +147,6 @@ _info(struct modinfo *modinfop) static void drv_init(void) { - dld_ctl_vmem = vmem_create("dld_ctl", (void *)1, MAXMIN, 1, - NULL, NULL, NULL, 1, VM_SLEEP | VMC_IDENTIFIER); drv_secobj_init(); dld_str_init(); /* @@ -229,7 +186,6 @@ drv_fini(void) return (err); drv_secobj_fini(); - vmem_destroy(dld_ctl_vmem); mod_hash_destroy_idhash(dld_ap_hashp); rw_destroy(&dld_ap_hash_lock); return (0); @@ -247,10 +203,10 @@ drv_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resp) switch (cmd) { case DDI_INFO_DEVT2INSTANCE: - *resp = (void *)0; + *resp = 0; break; case DDI_INFO_DEVT2DEVINFO: - *resp = (void *)dld_dip; + *resp = dld_dip; break; default: return (DDI_FAILURE); @@ -296,7 +252,7 @@ drv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) return (DDI_FAILURE); ASSERT(ddi_get_instance(dip) == 0); - + drv_init(); drv_set_opt(dip); /* @@ -325,6 +281,8 @@ drv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) return (DDI_FAILURE); ASSERT(dld_dip == dip); + if (drv_fini() != 0) + return (DDI_FAILURE); /* * Remove the control node. @@ -340,137 +298,63 @@ drv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) */ /*ARGSUSED*/ static int -drv_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp) +drv_open(dev_t *devp, int flag, int sflag, cred_t *credp) { - dld_ctl_str_t *ctls; - minor_t minor; - queue_t *oq = OTHERQ(rq); - - if (sflag == MODOPEN) - return (ENOTSUP); - /* - * This is a cloning driver and therefore each queue should only - * ever get opened once. + * Only the control node can be opened. */ - if (rq->q_ptr != NULL) - return (EBUSY); - - minor = (minor_t)(uintptr_t)vmem_alloc(dld_ctl_vmem, 1, VM_NOSLEEP); - if (minor == 0) - return (ENOMEM); - - ctls = kmem_zalloc(sizeof (dld_ctl_str_t), KM_NOSLEEP); - if (ctls == NULL) { - vmem_free(dld_ctl_vmem, (void *)(uintptr_t)minor, 1); - return (ENOMEM); - } - - ctls->cs_minor = minor; - ctls->cs_wq = WR(rq); - - rq->q_ptr = ctls; - oq->q_ptr = ctls; - - /* - * Enable the queue srv(9e) routine. - */ - qprocson(rq); - - /* - * Construct a cloned dev_t to hand back. - */ - *devp = makedevice(getmajor(*devp), ctls->cs_minor); - return (0); -} - -/* - * dld control node close procedure. - */ -static int -drv_close(queue_t *rq) -{ - dld_ctl_str_t *ctls; - - ctls = rq->q_ptr; - ASSERT(ctls != NULL); - - /* - * Disable the queue srv(9e) routine. - */ - qprocsoff(rq); - - vmem_free(dld_ctl_vmem, (void *)(uintptr_t)ctls->cs_minor, 1); - - kmem_free(ctls, sizeof (dld_ctl_str_t)); - + if (getminor(*devp) != DLD_CONTROL_MINOR) + return (ENODEV); return (0); } /* * DLDIOC_ATTR */ -static void -drv_ioc_attr(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_attr(void *karg, intptr_t arg, int mode, cred_t *cred) { - dld_ioc_attr_t *diap; + dld_ioc_attr_t *diap = karg; dls_dl_handle_t dlh; dls_vlan_t *dvp; int err; - queue_t *q = ctls->cs_wq; - - if ((err = miocpullup(mp, sizeof (dld_ioc_attr_t))) != 0) - goto failed; - - diap = (dld_ioc_attr_t *)mp->b_cont->b_rptr; if ((err = dls_devnet_hold_tmp(diap->dia_linkid, &dlh)) != 0) - goto failed; + return (err); if ((err = dls_vlan_hold(dls_devnet_mac(dlh), dls_devnet_vid(dlh), &dvp, B_FALSE, B_FALSE)) != 0) { dls_devnet_rele_tmp(dlh); - goto failed; + return (err); } mac_sdu_get(dvp->dv_dlp->dl_mh, NULL, &diap->dia_max_sdu); dls_vlan_rele(dvp); dls_devnet_rele_tmp(dlh); - miocack(q, mp, sizeof (dld_ioc_attr_t), 0); - return; - -failed: - ASSERT(err != 0); - miocnak(q, mp, 0, err); + return (0); } /* * DLDIOC_PHYS_ATTR */ -static void -drv_ioc_phys_attr(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_phys_attr(void *karg, intptr_t arg, int mode, cred_t *cred) { - dld_ioc_phys_attr_t *dipp; + dld_ioc_phys_attr_t *dipp = karg; int err; dls_dl_handle_t dlh; dls_dev_handle_t ddh; dev_t phydev; - queue_t *q = ctls->cs_wq; - - if ((err = miocpullup(mp, sizeof (dld_ioc_phys_attr_t))) != 0) - goto failed; - - dipp = (dld_ioc_phys_attr_t *)mp->b_cont->b_rptr; /* * Every physical link should have its physical dev_t kept in the * daemon. If not, it is not a valid physical link. */ - if (dls_mgmt_get_phydev(dipp->dip_linkid, &phydev) != 0) { - err = EINVAL; - goto failed; - } + if (dls_mgmt_get_phydev(dipp->dip_linkid, &phydev) != 0) + return (EINVAL); /* * Although this is a valid physical link, it might already be removed @@ -478,7 +362,7 @@ drv_ioc_phys_attr(dld_ctl_str_t *ctls, mblk_t *mp) * ENOENT in this case. */ if ((err = softmac_hold_device(phydev, &ddh)) != 0) - goto failed; + return (err); if (dls_devnet_hold_tmp(dipp->dip_linkid, &dlh) != 0) { /* @@ -499,24 +383,20 @@ drv_ioc_phys_attr(dld_ctl_str_t *ctls, mblk_t *mp) ddi_major_to_name(getmajor(phydev)), getminor(phydev) - 1); softmac_rele_device(ddh); - - miocack(q, mp, sizeof (dld_ioc_phys_attr_t), 0); - return; - -failed: - miocnak(q, mp, 0, err); + return (0); } /* * DLDIOC_SETPROP */ -static void -drv_ioc_prop_common(dld_ctl_str_t *ctls, mblk_t *mp, boolean_t set) +static int +drv_ioc_prop_common(dld_ioc_macprop_t *dipp, intptr_t arg, boolean_t set, + int mode) { - int err = EINVAL, dsize; - queue_t *q = ctls->cs_wq; - dld_ioc_macprop_t *dipp; - dls_dl_handle_t dlh; + int err = EINVAL; + size_t dsize; + dld_ioc_macprop_t *kdipp; + dls_dl_handle_t dlh; dls_vlan_t *dvp; datalink_id_t linkid; mac_prop_t macprop; @@ -524,32 +404,45 @@ drv_ioc_prop_common(dld_ctl_str_t *ctls, mblk_t *mp, boolean_t set) struct dlautopush *dlap; dld_ioc_zid_t *dzp; - if ((err = miocpullup(mp, sizeof (dld_ioc_macprop_t) - 1)) != 0) - goto done; - dipp = (dld_ioc_macprop_t *)mp->b_cont->b_rptr; - + /* + * We only use pr_valsize from dipp, as the caller only did a + * copyin() for sizeof (dld_ioc_prop_t), which doesn't cover + * the property data. We copyin the full dld_ioc_prop_t + * including the data into kdipp down below. + */ dsize = sizeof (dld_ioc_macprop_t) + dipp->pr_valsize - 1; - if ((err = miocpullup(mp, dsize)) != 0) + if (dsize < dipp->pr_valsize) + return (EINVAL); + + /* + * The property data is variable size, so we need to allocate + * a buffer for kernel use as this data was not part of the + * dipp allocation and copyin() done by the framework. + */ + if ((kdipp = kmem_alloc(dsize, KM_NOSLEEP)) == NULL) + return (ENOMEM); + if (ddi_copyin((void *)arg, kdipp, dsize, mode) != 0) { + err = EFAULT; goto done; - dipp = (dld_ioc_macprop_t *)mp->b_cont->b_rptr; + } - linkid = dipp->pr_linkid; + linkid = kdipp->pr_linkid; switch (dipp->pr_num) { case MAC_PROP_ZONE: if (set) { - dzp = (dld_ioc_zid_t *)dipp->pr_val; + dzp = (dld_ioc_zid_t *)kdipp->pr_val; err = dls_devnet_setzid(dzp->diz_link, dzp->diz_zid); goto done; } else { - cp = (uchar_t *)dipp->pr_val; + cp = (uchar_t *)kdipp->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; + dlap = (struct dlautopush *)kdipp->pr_val; err = drv_ioc_setap(linkid, dlap); goto done; } else { @@ -557,7 +450,7 @@ drv_ioc_prop_common(dld_ctl_str_t *ctls, mblk_t *mp, boolean_t set) goto done; } } else { - dlap = (struct dlautopush *)dipp->pr_val; + dlap = (struct dlautopush *)kdipp->pr_val; err = drv_ioc_getap(linkid, dlap); goto done; } @@ -575,124 +468,95 @@ drv_ioc_prop_common(dld_ctl_str_t *ctls, mblk_t *mp, boolean_t set) goto done; } - macprop.mp_name = dipp->pr_name; - macprop.mp_id = dipp->pr_num; - macprop.mp_flags = dipp->pr_flags; + macprop.mp_name = kdipp->pr_name; + macprop.mp_id = kdipp->pr_num; + macprop.mp_flags = kdipp->pr_flags; - if (set) + if (set) { err = mac_set_prop(dvp->dv_dlp->dl_mh, &macprop, - dipp->pr_val, dipp->pr_valsize); - else + kdipp->pr_val, kdipp->pr_valsize); + } else { err = mac_get_prop(dvp->dv_dlp->dl_mh, &macprop, - dipp->pr_val, dipp->pr_valsize); + kdipp->pr_val, kdipp->pr_valsize); + } dls_vlan_rele(dvp); dls_devnet_rele_tmp(dlh); done: - if (err == 0) - miocack(q, mp, dsize, 0); - else - miocnak(q, mp, 0, err); + if (!set && err == 0 && + ddi_copyout(kdipp, (void *)arg, dsize, mode) != 0) + err = EFAULT; + kmem_free(kdipp, dsize); + return (err); } -static void -drv_ioc_setprop(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_setprop(void *karg, intptr_t arg, int mode, cred_t *cred) { - drv_ioc_prop_common(ctls, mp, B_TRUE); + return (drv_ioc_prop_common(karg, arg, B_TRUE, mode)); } -static void -drv_ioc_getprop(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_getprop(void *karg, intptr_t arg, int mode, cred_t *cred) { - drv_ioc_prop_common(ctls, mp, B_FALSE); + return (drv_ioc_prop_common(karg, arg, B_FALSE, mode)); } /* * DLDIOC_CREATE_VLAN */ -static void -drv_ioc_create_vlan(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_create_vlan(void *karg, intptr_t arg, int mode, cred_t *cred) { - dld_ioc_create_vlan_t *dicp; - int err; - queue_t *q = ctls->cs_wq; - - if ((err = miocpullup(mp, sizeof (dld_ioc_create_vlan_t))) != 0) - goto failed; - - dicp = (dld_ioc_create_vlan_t *)mp->b_cont->b_rptr; + dld_ioc_create_vlan_t *dicp = karg; - if ((err = dls_devnet_create_vlan(dicp->dic_vlanid, - dicp->dic_linkid, dicp->dic_vid, dicp->dic_force)) != 0) { - goto failed; - } - - miocack(q, mp, 0, 0); - return; - -failed: - miocnak(q, mp, 0, err); + return (dls_devnet_create_vlan(dicp->dic_vlanid, dicp->dic_linkid, + dicp->dic_vid, dicp->dic_force)); } /* * DLDIOC_DELETE_VLAN */ -static void -drv_ioc_delete_vlan(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_delete_vlan(void *karg, intptr_t arg, int mode, cred_t *cred) { - dld_ioc_delete_vlan_t *didp; - int err; - queue_t *q = ctls->cs_wq; - - if ((err = miocpullup(mp, sizeof (dld_ioc_delete_vlan_t))) != 0) - goto done; - - didp = (dld_ioc_delete_vlan_t *)mp->b_cont->b_rptr; - err = dls_devnet_destroy_vlan(didp->did_linkid); + dld_ioc_delete_vlan_t *didp = karg; -done: - if (err == 0) - miocack(q, mp, 0, 0); - else - miocnak(q, mp, 0, err); + return (dls_devnet_destroy_vlan(didp->did_linkid)); } /* * DLDIOC_VLAN_ATTR */ -static void -drv_ioc_vlan_attr(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_vlan_attr(void *karg, intptr_t arg, int mode, cred_t *cred) { - dld_ioc_vlan_attr_t *divp; + dld_ioc_vlan_attr_t *divp = karg; dls_dl_handle_t dlh; uint16_t vid; dls_vlan_t *dvp; int err; - queue_t *q = ctls->cs_wq; - - if ((err = miocpullup(mp, sizeof (dld_ioc_vlan_attr_t))) != 0) - goto failed; - - divp = (dld_ioc_vlan_attr_t *)mp->b_cont->b_rptr; /* * Hold this link to prevent it from being deleted. */ - err = dls_devnet_hold_tmp(divp->div_vlanid, &dlh); - if (err != 0) - goto failed; + if ((err = dls_devnet_hold_tmp(divp->div_vlanid, &dlh)) != 0) + return (err); if ((vid = dls_devnet_vid(dlh)) == VLAN_ID_NONE) { dls_devnet_rele_tmp(dlh); - err = EINVAL; - goto failed; + return (EINVAL); } err = dls_vlan_hold(dls_devnet_mac(dlh), vid, &dvp, B_FALSE, B_FALSE); if (err != 0) { dls_devnet_rele_tmp(dlh); - err = EINVAL; - goto failed; + return (err); } divp->div_linkid = dls_devnet_linkid(dlh); @@ -702,11 +566,7 @@ drv_ioc_vlan_attr(dld_ctl_str_t *ctls, mblk_t *mp) dls_vlan_rele(dvp); dls_devnet_rele_tmp(dlh); - miocack(q, mp, sizeof (dld_ioc_vlan_attr_t), 0); - return; - -failed: - miocnak(q, mp, 0, err); + return (0); } /* @@ -715,26 +575,21 @@ failed: * This function handles two cases of link renaming. See more in comments above * dls_datalink_rename(). */ -static void -drv_ioc_rename(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_rename(void *karg, intptr_t arg, int mode, cred_t *cred) { - dld_ioc_rename_t *dir; + dld_ioc_rename_t *dir = karg; mod_hash_key_t key; mod_hash_val_t val; int err; - queue_t *q = ctls->cs_wq; - - if ((err = miocpullup(mp, sizeof (dld_ioc_rename_t))) != 0) - goto done; - dir = (dld_ioc_rename_t *)mp->b_cont->b_rptr; if ((err = dls_devnet_rename(dir->dir_linkid1, dir->dir_linkid2, - dir->dir_link)) != 0) { - goto done; - } + dir->dir_link)) != 0) + return (err); if (dir->dir_linkid2 == DATALINK_INVALID_LINKID) - goto done; + return (0); /* * if dir_linkid2 is not DATALINK_INVALID_LINKID, it means this @@ -750,42 +605,34 @@ drv_ioc_rename(dld_ctl_str_t *ctls, mblk_t *mp) 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); } static int drv_ioc_setap(datalink_id_t linkid, struct dlautopush *dlap) { dld_ap_t *dap; - int i, err; + int i; mod_hash_key_t key; - if (dlap->dap_npush == 0 || dlap->dap_npush > MAXAPUSH) { - err = EINVAL; - goto failed; - } + if (dlap->dap_npush == 0 || dlap->dap_npush > MAXAPUSH) + return (EINVAL); /* * Validate that the specified list of modules exist. */ for (i = 0; i < dlap->dap_npush; i++) { - if (fmodsw_find(dlap->dap_aplist[i], FMODSW_LOAD) == NULL) { - err = EINVAL; - goto failed; - } + if (fmodsw_find(dlap->dap_aplist[i], FMODSW_LOAD) == NULL) + return (EINVAL); } + key = (mod_hash_key_t)(uintptr_t)linkid; rw_enter(&dld_ap_hash_lock, RW_WRITER); @@ -793,13 +640,12 @@ drv_ioc_setap(datalink_id_t linkid, struct dlautopush *dlap) dap = kmem_zalloc(sizeof (dld_ap_t), KM_NOSLEEP); if (dap == NULL) { rw_exit(&dld_ap_hash_lock); - err = ENOMEM; - goto failed; + return (ENOMEM); } dap->da_linkid = linkid; - err = mod_hash_insert(dld_ap_hashp, key, (mod_hash_val_t)dap); - ASSERT(err == 0); + VERIFY(mod_hash_insert(dld_ap_hashp, key, + (mod_hash_val_t)dap) == 0); } /* @@ -814,24 +660,20 @@ drv_ioc_setap(datalink_id_t linkid, struct dlautopush *dlap) rw_exit(&dld_ap_hash_lock); return (0); - -failed: - return (err); } static int drv_ioc_getap(datalink_id_t linkid, struct dlautopush *dlap) { dld_ap_t *dap; - int i, err; + int i; rw_enter(&dld_ap_hash_lock, RW_READER); if (mod_hash_find(dld_ap_hashp, (mod_hash_key_t)(uintptr_t)linkid, (mod_hash_val_t *)&dap) != 0) { - err = ENOENT; rw_exit(&dld_ap_hash_lock); - goto failed; + return (ENOENT); } /* @@ -846,9 +688,6 @@ drv_ioc_getap(datalink_id_t linkid, struct dlautopush *dlap) rw_exit(&dld_ap_hash_lock); return (0); - -failed: - return (err); } static int @@ -874,106 +713,13 @@ drv_ioc_clrap(datalink_id_t linkid) /* * DLDIOC_DOORSERVER */ -static void -drv_ioc_doorserver(dld_ctl_str_t *ctls, mblk_t *mp) -{ - queue_t *q = ctls->cs_wq; - dld_ioc_door_t *did; - int err; - - if ((err = miocpullup(mp, sizeof (dld_ioc_door_t))) != 0) - goto done; - - did = (dld_ioc_door_t *)mp->b_cont->b_rptr; - err = dls_mgmt_door_set(did->did_start_door); - -done: - if (err == 0) - miocack(q, mp, 0, 0); - else - miocnak(q, mp, 0, err); -} - -/* - * Process an IOCTL message received by the control node. - */ -static void -drv_ioc(dld_ctl_str_t *ctls, mblk_t *mp) -{ - uint_t cmd; - - cmd = ((struct iocblk *)mp->b_rptr)->ioc_cmd; - switch (cmd) { - case DLDIOC_ATTR: - drv_ioc_attr(ctls, mp); - return; - case DLDIOC_PHYS_ATTR: - drv_ioc_phys_attr(ctls, mp); - return; - case DLDIOC_SECOBJ_SET: - drv_ioc_secobj_set(ctls, mp); - return; - case DLDIOC_SECOBJ_GET: - drv_ioc_secobj_get(ctls, mp); - return; - case DLDIOC_SECOBJ_UNSET: - drv_ioc_secobj_unset(ctls, mp); - return; - case DLDIOC_SETMACPROP: - drv_ioc_setprop(ctls, mp); - return; - case DLDIOC_GETMACPROP: - drv_ioc_getprop(ctls, mp); - return; - case DLDIOC_CREATE_VLAN: - drv_ioc_create_vlan(ctls, mp); - return; - case DLDIOC_DELETE_VLAN: - drv_ioc_delete_vlan(ctls, mp); - return; - case DLDIOC_VLAN_ATTR: - drv_ioc_vlan_attr(ctls, mp); - return; - case DLDIOC_DOORSERVER: - drv_ioc_doorserver(ctls, mp); - return; - case DLDIOC_RENAME: - drv_ioc_rename(ctls, mp); - return; - default: - miocnak(ctls->cs_wq, mp, 0, ENOTSUP); - return; - } -} - -/* - * Write side put routine of the dld control node. - */ -static void -drv_uw_put(queue_t *q, mblk_t *mp) -{ - dld_ctl_str_t *ctls = q->q_ptr; - - switch (mp->b_datap->db_type) { - case M_IOCTL: - drv_ioc(ctls, mp); - break; - default: - freemsg(mp); - break; - } -} - -/* - * Write-side service procedure. - */ -void -drv_uw_srv(queue_t *q) +/* ARGSUSED */ +static int +drv_ioc_doorserver(void *karg, intptr_t arg, int mode, cred_t *cred) { - mblk_t *mp; + dld_ioc_door_t *did = karg; - while (mp = getq(q)) - drv_uw_put(q, mp); + return (dls_mgmt_door_set(did->did_start_door)); } /* @@ -1057,68 +803,57 @@ drv_secobj_fini(void) rw_destroy(&drv_secobj_lock); } -static void -drv_ioc_secobj_set(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_secobj_set(void *karg, intptr_t arg, int mode, cred_t *cred) { - dld_ioc_secobj_set_t *ssp; + dld_ioc_secobj_set_t *ssp = karg; dld_secobj_t *sobjp, *objp; - int err = EINVAL; - queue_t *q = ctls->cs_wq; - - if ((err = miocpullup(mp, sizeof (dld_ioc_secobj_set_t))) != 0) - goto failed; + int err; - ssp = (dld_ioc_secobj_set_t *)mp->b_cont->b_rptr; sobjp = &ssp->ss_obj; if (sobjp->so_class != DLD_SECOBJ_CLASS_WEP && sobjp->so_class != DLD_SECOBJ_CLASS_WPA) - goto failed; + return (EINVAL); if (sobjp->so_name[DLD_SECOBJ_NAME_MAX - 1] != '\0' || sobjp->so_len > DLD_SECOBJ_VAL_MAX) - goto failed; + return (EINVAL); rw_enter(&drv_secobj_lock, RW_WRITER); err = mod_hash_find(drv_secobj_hash, (mod_hash_key_t)sobjp->so_name, (mod_hash_val_t *)&objp); if (err == 0) { if ((ssp->ss_flags & DLD_SECOBJ_OPT_CREATE) != 0) { - err = EEXIST; rw_exit(&drv_secobj_lock); - goto failed; + return (EEXIST); } } else { ASSERT(err == MH_ERR_NOTFOUND); if ((ssp->ss_flags & DLD_SECOBJ_OPT_CREATE) == 0) { - err = ENOENT; rw_exit(&drv_secobj_lock); - goto failed; + return (ENOENT); } objp = kmem_cache_alloc(drv_secobj_cachep, KM_SLEEP); (void) strlcpy(objp->so_name, sobjp->so_name, DLD_SECOBJ_NAME_MAX); - err = mod_hash_insert(drv_secobj_hash, - (mod_hash_key_t)objp->so_name, (mod_hash_val_t)objp); - ASSERT(err == 0); + VERIFY(mod_hash_insert(drv_secobj_hash, + (mod_hash_key_t)objp->so_name, (mod_hash_val_t)objp) == 0); } bcopy(sobjp->so_val, objp->so_val, sobjp->so_len); objp->so_len = sobjp->so_len; objp->so_class = sobjp->so_class; rw_exit(&drv_secobj_lock); - miocack(q, mp, 0, 0); - return; - -failed: - ASSERT(err != 0); - miocnak(q, mp, 0, err); + return (0); } typedef struct dld_secobj_state { uint_t ss_free; uint_t ss_count; int ss_rc; + int ss_mode; dld_secobj_t *ss_objp; } dld_secobj_state_t; @@ -1133,36 +868,29 @@ drv_secobj_walker(mod_hash_key_t key, mod_hash_val_t *val, void *arg) statep->ss_rc = ENOSPC; return (MH_WALK_TERMINATE); } - bcopy(sobjp, statep->ss_objp, sizeof (dld_secobj_t)); + if (ddi_copyout(sobjp, statep->ss_objp, sizeof (*sobjp), + statep->ss_mode) != 0) { + statep->ss_rc = EFAULT; + return (MH_WALK_TERMINATE); + } statep->ss_objp++; statep->ss_free -= sizeof (dld_secobj_t); statep->ss_count++; return (MH_WALK_CONTINUE); } -static void -drv_ioc_secobj_get(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_secobj_get(void *karg, intptr_t arg, int mode, cred_t *cred) { - dld_ioc_secobj_get_t *sgp; + dld_ioc_secobj_get_t *sgp = karg; dld_secobj_t *sobjp, *objp; - int err = EINVAL; - uint_t extra = 0; - queue_t *q = ctls->cs_wq; - mblk_t *bp; - - if ((err = miocpullup(mp, sizeof (dld_ioc_secobj_get_t))) != 0) - goto failed; - - if ((bp = msgpullup(mp->b_cont, -1)) == NULL) - goto failed; + int err; - freemsg(mp->b_cont); - mp->b_cont = bp; - sgp = (dld_ioc_secobj_get_t *)bp->b_rptr; sobjp = &sgp->sg_obj; if (sobjp->so_name[DLD_SECOBJ_NAME_MAX - 1] != '\0') - goto failed; + return (EINVAL); rw_enter(&drv_secobj_lock, RW_READER); if (sobjp->so_name[0] != '\0') { @@ -1170,9 +898,8 @@ drv_ioc_secobj_get(dld_ctl_str_t *ctls, mblk_t *mp) (mod_hash_key_t)sobjp->so_name, (mod_hash_val_t *)&objp); if (err != 0) { ASSERT(err == MH_ERR_NOTFOUND); - err = ENOENT; rw_exit(&drv_secobj_lock); - goto failed; + return (ENOENT); } bcopy(objp->so_val, sobjp->so_val, objp->so_len); sobjp->so_len = objp->so_len; @@ -1181,65 +908,212 @@ drv_ioc_secobj_get(dld_ctl_str_t *ctls, mblk_t *mp) } else { dld_secobj_state_t state; - state.ss_free = MBLKL(bp) - sizeof (dld_ioc_secobj_get_t); + state.ss_free = sgp->sg_size - sizeof (dld_ioc_secobj_get_t); state.ss_count = 0; state.ss_rc = 0; - state.ss_objp = (dld_secobj_t *)(sgp + 1); + state.ss_mode = mode; + state.ss_objp = (dld_secobj_t *)((uchar_t *)arg + + sizeof (dld_ioc_secobj_get_t)); + mod_hash_walk(drv_secobj_hash, drv_secobj_walker, &state); if (state.ss_rc != 0) { - err = state.ss_rc; rw_exit(&drv_secobj_lock); - goto failed; + return (state.ss_rc); } sgp->sg_count = state.ss_count; - extra = state.ss_count * sizeof (dld_secobj_t); } rw_exit(&drv_secobj_lock); - miocack(q, mp, sizeof (dld_ioc_secobj_get_t) + extra, 0); - return; - -failed: - ASSERT(err != 0); - miocnak(q, mp, 0, err); - + return (0); } -static void -drv_ioc_secobj_unset(dld_ctl_str_t *ctls, mblk_t *mp) +/* ARGSUSED */ +static int +drv_ioc_secobj_unset(void *karg, intptr_t arg, int mode, cred_t *cred) { - dld_ioc_secobj_unset_t *sup; + dld_ioc_secobj_unset_t *sup = karg; dld_secobj_t *objp; mod_hash_val_t val; - int err = EINVAL; - queue_t *q = ctls->cs_wq; - - if ((err = miocpullup(mp, sizeof (dld_ioc_secobj_unset_t))) != 0) - goto failed; + int err; - sup = (dld_ioc_secobj_unset_t *)mp->b_cont->b_rptr; if (sup->su_name[DLD_SECOBJ_NAME_MAX - 1] != '\0') - goto failed; + return (EINVAL); rw_enter(&drv_secobj_lock, RW_WRITER); err = mod_hash_find(drv_secobj_hash, (mod_hash_key_t)sup->su_name, (mod_hash_val_t *)&objp); if (err != 0) { ASSERT(err == MH_ERR_NOTFOUND); - err = ENOENT; rw_exit(&drv_secobj_lock); - goto failed; + return (ENOENT); } - err = mod_hash_remove(drv_secobj_hash, (mod_hash_key_t)sup->su_name, - (mod_hash_val_t *)&val); - ASSERT(err == 0); + VERIFY(mod_hash_remove(drv_secobj_hash, (mod_hash_key_t)sup->su_name, + (mod_hash_val_t *)&val) == 0); ASSERT(objp == (dld_secobj_t *)val); kmem_cache_free(drv_secobj_cachep, objp); rw_exit(&drv_secobj_lock); - miocack(q, mp, 0, 0); - return; + return (0); +} + +static dld_ioc_info_t drv_ioc_list[] = { + {DLDIOC_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_attr_t), + drv_ioc_attr}, + {DLDIOC_PHYS_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_phys_attr_t), + drv_ioc_phys_attr}, + {DLDIOC_SECOBJ_SET, DLDCOPYIN | DLDDLCONFIG, + sizeof (dld_ioc_secobj_set_t), drv_ioc_secobj_set}, + {DLDIOC_SECOBJ_GET, DLDCOPYINOUT | DLDDLCONFIG, + sizeof (dld_ioc_secobj_get_t), drv_ioc_secobj_get}, + {DLDIOC_SECOBJ_UNSET, DLDCOPYIN | DLDDLCONFIG, + sizeof (dld_ioc_secobj_unset_t), drv_ioc_secobj_unset}, + {DLDIOC_CREATE_VLAN, DLDCOPYIN | DLDDLCONFIG, + sizeof (dld_ioc_create_vlan_t), drv_ioc_create_vlan}, + {DLDIOC_DELETE_VLAN, DLDCOPYIN | DLDDLCONFIG, + sizeof (dld_ioc_delete_vlan_t), + drv_ioc_delete_vlan}, + {DLDIOC_VLAN_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_vlan_attr_t), + drv_ioc_vlan_attr}, + {DLDIOC_DOORSERVER, DLDCOPYIN | DLDDLCONFIG, sizeof (dld_ioc_door_t), + drv_ioc_doorserver}, + {DLDIOC_RENAME, DLDCOPYIN | DLDDLCONFIG, sizeof (dld_ioc_rename_t), + drv_ioc_rename}, + {DLDIOC_GETMACPROP, DLDCOPYIN, sizeof (dld_ioc_macprop_t), + drv_ioc_getprop}, + {DLDIOC_SETMACPROP, DLDCOPYIN | DLDDLCONFIG, sizeof (dld_ioc_macprop_t), + drv_ioc_setprop} +}; + +typedef struct dld_ioc_modentry { + uint16_t dim_modid; /* Top 16 bits of ioctl command */ + char *dim_modname; /* Module to be loaded */ + dld_ioc_info_t *dim_list; /* array of ioctl structures */ + uint_t dim_count; /* number of elements in dim_list */ +} dld_ioc_modentry_t; + +/* + * For all modules except for dld, dim_list and dim_count are assigned + * when the modules register their ioctls in dld_ioc_register(). We + * can statically initialize dld's ioctls in-line here; there's no + * need for it to call dld_ioc_register() itself. + */ +static dld_ioc_modentry_t dld_ioc_modtable[] = { + {DLD_IOC, "dld", drv_ioc_list, DLDIOCCNT(drv_ioc_list)}, + {AGGR_IOC, "aggr", NULL, 0}, + {VNIC_IOC, "vnic", NULL, 0} +}; +#define DLDIOC_CNT \ + (sizeof (dld_ioc_modtable) / sizeof (dld_ioc_modentry_t)) + +static dld_ioc_modentry_t * +dld_ioc_findmod(uint16_t modid) +{ + int i; + + for (i = 0; i < DLDIOC_CNT; i++) { + if (modid == dld_ioc_modtable[i].dim_modid) + return (&dld_ioc_modtable[i]); + } + return (NULL); +} + +int +dld_ioc_register(uint16_t modid, dld_ioc_info_t *list, uint_t count) +{ + dld_ioc_modentry_t *dim = dld_ioc_findmod(modid); + + if (dim == NULL) + return (ENOENT); + + dim->dim_list = list; + dim->dim_count = count; + return (0); +} + +void +dld_ioc_unregister(uint16_t modid) +{ + VERIFY(dld_ioc_register(modid, NULL, 0) == 0); +} -failed: - ASSERT(err != 0); - miocnak(q, mp, 0, err); +/* + * The general design with GLDv3 ioctls is that all ioctls issued + * through /dev/dld go through this drv_ioctl() function. This + * function handles all ioctls on behalf of modules listed in + * dld_ioc_modtable. + * + * When an ioctl is received, this function looks for the associated + * module-id-specific ioctl information using dld_ioc_findmod(). The + * call to ddi_hold_devi_by_instance() on the associated device will + * cause the kernel module responsible for the ioctl to be loaded if + * it's not already loaded, which should result in that module calling + * dld_ioc_register(), thereby filling in the dim_list containing the + * details for the ioctl being processed. + * + * This function can then perform operations such as copyin() data and + * do credential checks based on the registered ioctl information, + * then issue the callback function di_func() registered by the + * responsible module. Upon return, the appropriate copyout() + * operation can be performed and the operation completes. + */ +/* ARGSUSED */ +static int +drv_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred, int *rvalp) +{ + dld_ioc_modentry_t *dim; + dld_ioc_info_t *info; + dev_info_t *dip = NULL; + void *buf = NULL; + size_t sz; + int i, err; + + if ((dim = dld_ioc_findmod(DLD_IOC_MODID(cmd))) == NULL) + return (ENOTSUP); + + dip = ddi_hold_devi_by_instance(ddi_name_to_major(dim->dim_modname), + 0, 0); + if (dip == NULL || dim->dim_list == NULL) { + err = ENODEV; + goto done; + } + + for (i = 0; i < dim->dim_count; i++) { + if (cmd == dim->dim_list[i].di_cmd) + break; + } + if (i == dim->dim_count) { + err = ENOTSUP; + goto done; + } + + info = &dim->dim_list[i]; + + if ((info->di_flags & DLDDLCONFIG) && secpolicy_dl_config(cred) != 0) { + err = EPERM; + goto done; + } + + sz = info->di_argsize; + if ((buf = kmem_zalloc(sz, KM_NOSLEEP)) == NULL) { + err = ENOMEM; + goto done; + } + + if ((info->di_flags & DLDCOPYIN) && + ddi_copyin((void *)arg, buf, sz, mode) != 0) { + err = EFAULT; + goto done; + } + + err = info->di_func(buf, arg, mode, cred); + + if ((info->di_flags & DLDCOPYOUT) && + ddi_copyout(buf, (void *)arg, sz, mode) != 0 && err == 0) + err = EFAULT; + +done: + if (buf != NULL) + kmem_free(buf, sz); + if (dip != NULL) + ddi_release_devi(dip); + return (err); } diff --git a/usr/src/uts/common/io/dld/dld_str.c b/usr/src/uts/common/io/dld/dld_str.c index bb39729813..8694b9d6c4 100644 --- a/usr/src/uts/common/io/dld/dld_str.c +++ b/usr/src/uts/common/io/dld/dld_str.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Data-Link Driver */ @@ -566,7 +564,8 @@ dld_init_ops(struct dev_ops *ops, const char *name) stream->st_wrinit = wq; ops->devo_cb_ops->cb_str = stream; - ops->devo_getinfo = &dld_getinfo; + if (ops->devo_getinfo == NULL) + ops->devo_getinfo = &dld_getinfo; } void diff --git a/usr/src/uts/common/io/ipw/ipw2100.c b/usr/src/uts/common/io/ipw/ipw2100.c index 2e3bd21760..ad3fde641c 100644 --- a/usr/src/uts/common/io/ipw/ipw2100.c +++ b/usr/src/uts/common/io/ipw/ipw2100.c @@ -30,8 +30,6 @@ * SUCH DAMAGE. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/byteorder.h> #include <sys/conf.h> @@ -2182,20 +2180,11 @@ ipw2100_ioctl(struct ipw2100_softc *sc, queue_t *q, mblk_t *m) return (IEEE80211_IOCTL_NOT_REQUIRED); } - if (need_privilege) { - /* - * Check for specific net_config privilege on Solaris 10+. - * Otherwise just check for root access ... - */ - if (secpolicy_net_config != NULL) - ret = secpolicy_net_config(iocp->ioc_cr, B_FALSE); - else - ret = drv_priv(iocp->ioc_cr); - if (ret != 0) { - miocnak(q, m, 0, ret); /* ret is errno */ - return (IEEE80211_IOCTL_NOT_REQUIRED); - } + if (need_privilege && (ret = secpolicy_dl_config(iocp->ioc_cr)) != 0) { + miocnak(q, m, 0, ret); + return (IEEE80211_IOCTL_NOT_REQUIRED); } + /* * sanity check */ diff --git a/usr/src/uts/common/io/iwi/ipw2200.c b/usr/src/uts/common/io/iwi/ipw2200.c index 4e03f960c4..a3d9c696a5 100644 --- a/usr/src/uts/common/io/iwi/ipw2200.c +++ b/usr/src/uts/common/io/iwi/ipw2200.c @@ -30,8 +30,6 @@ * SUCH DAMAGE. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/byteorder.h> #include <sys/conf.h> @@ -2405,23 +2403,14 @@ ipw2200_ioctl(struct ipw2200_softc *sc, queue_t *q, mblk_t *m) return (IEEE80211_IOCTL_NOT_REQUIRED); } - if (need_privilege) { + if (need_privilege && (ret = secpolicy_dl_config(iocp->ioc_cr)) != 0) { + miocnak(q, m, 0, ret); /* - * Check for specific net_config privilege on Solaris 10+. - * Otherwise just check for root access ... + * privilege check fail, do not need net80211 either */ - if (secpolicy_net_config != NULL) - ret = secpolicy_net_config(iocp->ioc_cr, B_FALSE); - else - ret = drv_priv(iocp->ioc_cr); - if (ret != 0) { - miocnak(q, m, 0, ret); - /* - * privilege check fail, do not need net80211 either - */ - return (IEEE80211_IOCTL_NOT_REQUIRED); - } + return (IEEE80211_IOCTL_NOT_REQUIRED); } + /* * sanity check */ diff --git a/usr/src/uts/common/io/net80211/net80211_ioctl.c b/usr/src/uts/common/io/net80211/net80211_ioctl.c index 3bd4ba29cc..b6d515bd36 100644 --- a/usr/src/uts/common/io/net80211/net80211_ioctl.c +++ b/usr/src/uts/common/io/net80211/net80211_ioctl.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,8 +31,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/param.h> #include <sys/types.h> #include <sys/errno.h> @@ -1809,15 +1807,9 @@ ieee80211_ioctl(struct ieee80211com *ic, queue_t *wq, mblk_t *mp) return (EINVAL); } - if (need_privilege) { - /* - * Check for specific net_config privilege on Solaris 10+. - */ - err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); - if (err != 0) { - miocnak(wq, mp, 0, err); - return (err); - } + if (need_privilege && (err = secpolicy_dl_config(iocp->ioc_cr)) != 0) { + miocnak(wq, mp, 0, err); + return (err); } IEEE80211_LOCK(ic); diff --git a/usr/src/uts/common/io/pcan/pcan.c b/usr/src/uts/common/io/pcan/pcan.c index 83e9fca5b3..734bc145ae 100644 --- a/usr/src/uts/common/io/pcan/pcan.c +++ b/usr/src/uts/common/io/pcan/pcan.c @@ -35,8 +35,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/conf.h> #include <sys/ddi.h> #include <sys/sunddi.h> @@ -4038,13 +4036,8 @@ pcan_ioctl(void *arg, queue_t *wq, mblk_t *mp) break; } - /* Check net_config privilege */ - if (need_privilege) { - if (ret = secpolicy_net_config(iocp->ioc_cr, B_FALSE)) { - miocnak(wq, mp, 0, ret); - return; - } - } - - pcan_wlan_ioctl(pcan_p, wq, mp, cmd); + if (need_privilege && (ret = secpolicy_dl_config(iocp->ioc_cr)) != 0) + miocnak(wq, mp, 0, ret); + else + pcan_wlan_ioctl(pcan_p, wq, mp, cmd); } diff --git a/usr/src/uts/common/io/pcwl/pcwl.c b/usr/src/uts/common/io/pcwl/pcwl.c index 19344459a3..dbd065761a 100644 --- a/usr/src/uts/common/io/pcwl/pcwl.c +++ b/usr/src/uts/common/io/pcwl/pcwl.c @@ -35,8 +35,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/conf.h> #include <sys/ddi.h> #include <sys/sunddi.h> @@ -3779,20 +3777,15 @@ pcwl_ioctl(void *arg, queue_t *wq, mblk_t *mp) miocnak(wq, mp, 0, EINVAL); return; case WLAN_GET_PARAM: - need_privilege = B_TRUE; + need_privilege = B_FALSE; break; case WLAN_SET_PARAM: case WLAN_COMMAND: break; } - /* - * Check net_config privilege - */ - if (need_privilege) { - if (ret = secpolicy_net_config(iocp->ioc_cr, B_FALSE)) { - miocnak(wq, mp, 0, ret); - return; - } - } - pcwl_wlan_ioctl(pcwl_p, wq, mp, cmd); + + if (need_privilege && (ret = secpolicy_dl_config(iocp->ioc_cr)) != 0) + miocnak(wq, mp, 0, ret); + else + pcwl_wlan_ioctl(pcwl_p, wq, mp, cmd); } diff --git a/usr/src/uts/common/io/vnic/vnic_ctl.c b/usr/src/uts/common/io/vnic/vnic_ctl.c index 77aab2f7f1..f280efbadc 100644 --- a/usr/src/uts/common/io/vnic/vnic_ctl.c +++ b/usr/src/uts/common/io/vnic/vnic_ctl.c @@ -23,109 +23,70 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Virtual Network Interface Card (VNIC) */ -#include <sys/ddi.h> -#include <sys/strsun.h> -#include <sys/dld.h> -#include <sys/dld_impl.h> #include <sys/conf.h> #include <sys/modctl.h> -#include <sys/stat.h> #include <sys/vnic.h> #include <sys/vnic_impl.h> #include <inet/common.h> /* module description */ #define VNIC_LINKINFO "VNIC MAC" -#define VNIC_DRIVER_NAME "vnic" /* device info ptr, only one for instance 0 */ static dev_info_t *vnic_dip = NULL; - -/* for control interface */ static int vnic_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); static int vnic_attach(dev_info_t *, ddi_attach_cmd_t); static int vnic_detach(dev_info_t *, ddi_detach_cmd_t); -static int vnic_open(queue_t *, dev_t *, int, int, cred_t *); -static int vnic_close(queue_t *); -static void vnic_wput(queue_t *, mblk_t *); -static void vnic_ioctl(queue_t *, mblk_t *); - -static int vnic_ioc_create(mblk_t *, int); -static int vnic_ioc_modify(mblk_t *, int); -static int vnic_ioc_delete(mblk_t *, int); -static int vnic_ioc_info(mblk_t *, int); - -typedef struct ioc_cmd_s { - int ic_cmd; - int (*ic_func)(mblk_t *, int); -} ioc_cmd_t; - -static ioc_cmd_t ioc_cmd[] = { - {VNIC_IOC_CREATE, vnic_ioc_create}, - {VNIC_IOC_DELETE, vnic_ioc_delete}, - {VNIC_IOC_INFO, vnic_ioc_info}, - {VNIC_IOC_MODIFY, vnic_ioc_modify} -}; - -#define IOC_CMD_SZ (sizeof (ioc_cmd) / sizeof (ioc_cmd_t)) - -/* - * mi_hiwat is set to 1 because of the flow control mechanism implemented - * in dld. refer to the comments in dld_str.c for details. - */ -static struct module_info vnic_module_info = { - 0, - VNIC_DRIVER_NAME, - 0, - INFPSZ, - 1, - 0 -}; - -static struct qinit vnic_r_qinit = { /* read queues */ - NULL, - NULL, - vnic_open, - vnic_close, - NULL, - &vnic_module_info +static dld_ioc_func_t vnic_ioc_create, vnic_ioc_modify, vnic_ioc_delete, + vnic_ioc_info; + +static dld_ioc_info_t vnic_ioc_list[] = { + {VNIC_IOC_CREATE, DLDCOPYIN | DLDDLCONFIG, sizeof (vnic_ioc_create_t), + vnic_ioc_create}, + {VNIC_IOC_DELETE, DLDCOPYIN | DLDDLCONFIG, sizeof (vnic_ioc_delete_t), + vnic_ioc_delete}, + {VNIC_IOC_INFO, DLDCOPYINOUT, sizeof (vnic_ioc_info_t), + vnic_ioc_info}, + {VNIC_IOC_MODIFY, DLDCOPYIN | DLDDLCONFIG, sizeof (vnic_ioc_modify_t), + vnic_ioc_modify} }; -static struct qinit vnic_w_qinit = { /* write queues */ - (pfi_t)dld_wput, - (pfi_t)dld_wsrv, - NULL, - NULL, - NULL, - &vnic_module_info +static struct cb_ops vnic_cb_ops = { + nulldev, /* open */ + nulldev, /* close */ + nulldev, /* strategy */ + nulldev, /* print */ + nodev, /* dump */ + nodev, /* read */ + nodev, /* write */ + nodev, /* ioctl */ + nodev, /* devmap */ + nodev, /* mmap */ + nodev, /* segmap */ + nochpoll, /* poll */ + ddi_prop_op, /* cb_prop_op */ + 0, /* streamtab */ + D_MP /* Driver compatibility flag */ }; -/* - * Entry points for vnic control node - */ -static struct qinit vnic_w_ctl_qinit = { - (pfi_t)vnic_wput, - NULL, - NULL, - NULL, - NULL, - &vnic_module_info +static struct dev_ops vnic_dev_ops = { + DEVO_REV, /* devo_rev */ + 0, /* refcnt */ + vnic_getinfo, /* get_dev_info */ + nulldev, /* identify */ + nulldev, /* probe */ + vnic_attach, /* attach */ + vnic_detach, /* detach */ + nodev, /* reset */ + &vnic_cb_ops, /* driver operations */ + NULL, /* bus operations */ + nodev /* dev power */ }; -static struct streamtab vnic_streamtab = { - &vnic_r_qinit, - &vnic_w_qinit -}; - -DDI_DEFINE_STREAM_OPS(vnic_dev_ops, nulldev, nulldev, vnic_attach, vnic_detach, - nodev, vnic_getinfo, D_MP, &vnic_streamtab); - static struct modldrv vnic_modldrv = { &mod_driverops, /* Type of module. This one is a driver */ VNIC_LINKINFO, /* short description */ @@ -141,13 +102,22 @@ static struct modlinkage modlinkage = { int _init(void) { - return (mod_install(&modlinkage)); + int err; + + mac_init_ops(&vnic_dev_ops, "vnic"); + if ((err = mod_install(&modlinkage)) != 0) + mac_fini_ops(&vnic_dev_ops); + return (err); } int _fini(void) { - return (mod_remove(&modlinkage)); + int err; + + if ((err = mod_remove(&modlinkage)) == 0) + mac_fini_ops(&vnic_dev_ops); + return (err); } int @@ -156,106 +126,6 @@ _info(struct modinfo *modinfop) return (mod_info(&modlinkage, modinfop)); } -static int -vnic_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp) -{ - if (q->q_ptr != NULL) - return (EBUSY); - - if (getminor(*devp) == VNIC_CTL_NODE_MINOR) { - dld_str_t *dsp; - - dsp = dld_str_create(q, DLD_CONTROL, getmajor(*devp), - DL_STYLE1); - if (dsp == NULL) - return (ENOSR); - - /* - * The ioctl handling callback to process control ioctl - * messages; see comments above dld_ioctl() for details. - */ - dsp->ds_ioctl = vnic_ioctl; - - /* - * The VNIC control node uses its own set of entry points. - */ - WR(q)->q_qinfo = &vnic_w_ctl_qinit; - *devp = makedevice(getmajor(*devp), dsp->ds_minor); - qprocson(q); - return (0); - } - return (dld_open(q, devp, flag, sflag, credp)); -} - -static int -vnic_close(queue_t *q) -{ - dld_str_t *dsp = q->q_ptr; - - if (dsp->ds_type == DLD_CONTROL) { - qprocsoff(q); - dld_finish_pending_task(dsp); - dsp->ds_ioctl = NULL; - dld_str_destroy(dsp); - return (0); - } - return (dld_close(q)); -} - -static void -vnic_ioctl(queue_t *wq, mblk_t *mp) -{ - /* LINTED alignment */ - struct iocblk *iocp = (struct iocblk *)mp->b_rptr; - int i, err = EINVAL; - mblk_t *nmp; - - if (mp->b_cont == NULL) { - err = EINVAL; - goto done; - } - - /* - * Construct contiguous message - */ - if ((nmp = msgpullup(mp->b_cont, -1)) == NULL) { - freemsg(mp->b_cont); - err = ENOMEM; - goto done; - } - - freemsg(mp->b_cont); - mp->b_cont = nmp; - - for (i = 0; i < IOC_CMD_SZ; i++) { - if (iocp->ioc_cmd == ioc_cmd[i].ic_cmd) { - err = ioc_cmd[i].ic_func(mp, (int)iocp->ioc_flag); - break; - } - } - - if (err == 0) { - int len = 0; - - if (mp->b_cont != NULL) - len = MBLKL(mp->b_cont); - miocack(wq, mp, len, 0); - return; - } - -done: - miocnak(wq, mp, 0, err); -} - -static void -vnic_wput(queue_t *q, mblk_t *mp) -{ - if (DB_TYPE(mp) == M_IOCTL) - dld_ioctl(q, mp); - else - freemsg(mp); -} - static void vnic_init(void) { @@ -288,7 +158,7 @@ vnic_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, *result = vnic_dip; return (DDI_SUCCESS); case DDI_INFO_DEVT2INSTANCE: - *result = NULL; + *result = 0; return (DDI_SUCCESS); } return (DDI_FAILURE); @@ -304,11 +174,9 @@ vnic_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) return (DDI_FAILURE); } - /* create minor node for control interface */ - if (ddi_create_minor_node(dip, VNIC_CTL_NODE_NAME, S_IFCHR, - VNIC_CTL_NODE_MINOR, DDI_PSEUDO, 0) != DDI_SUCCESS) { + if (dld_ioc_register(VNIC_IOC, vnic_ioc_list, + DLDIOCCNT(vnic_ioc_list)) != 0) return (DDI_FAILURE); - } vnic_dip = dip; vnic_init(); @@ -338,7 +206,7 @@ vnic_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) vnic_dip = NULL; vnic_fini(); - ddi_remove_minor_node(dip, VNIC_CTL_NODE_NAME); + dld_ioc_unregister(VNIC_IOC); return (DDI_SUCCESS); @@ -351,98 +219,80 @@ vnic_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) } /* - * Process a VNICIOC_CREATE request. + * Process a VNIC_IOC_CREATE request. */ +/* ARGSUSED */ static int -vnic_ioc_create(mblk_t *mp, int mode) +vnic_ioc_create(void *karg, intptr_t arg, int mode, cred_t *cred) { - STRUCT_HANDLE(vnic_ioc_create, create_arg); - int rc = 0; + vnic_ioc_create_t *create_arg = karg; int mac_len; uchar_t mac_addr[MAXMACADDRLEN]; datalink_id_t vnic_id, linkid; vnic_mac_addr_type_t mac_addr_type; - STRUCT_SET_HANDLE(create_arg, mode, (void *)mp->b_cont->b_rptr); - if (MBLKL(mp->b_cont) < STRUCT_SIZE(create_arg)) - return (EINVAL); - /* * VNIC link id */ - vnic_id = STRUCT_FGET(create_arg, vc_vnic_id); + vnic_id = create_arg->vc_vnic_id; /* * Linkid of the link the VNIC is defined on top of. */ - linkid = STRUCT_FGET(create_arg, vc_link_id); + linkid = create_arg->vc_link_id; /* MAC address */ - mac_addr_type = STRUCT_FGET(create_arg, vc_mac_addr_type); - mac_len = STRUCT_FGET(create_arg, vc_mac_len); + mac_addr_type = create_arg->vc_mac_addr_type; + mac_len = create_arg->vc_mac_len; switch (mac_addr_type) { case VNIC_MAC_ADDR_TYPE_FIXED: - bcopy(STRUCT_FGET(create_arg, vc_mac_addr), mac_addr, - MAXMACADDRLEN); + bcopy(create_arg->vc_mac_addr, mac_addr, MAXMACADDRLEN); break; default: return (ENOTSUP); } - rc = vnic_dev_create(vnic_id, linkid, mac_len, mac_addr); - return (rc); + return (vnic_dev_create(vnic_id, linkid, mac_len, mac_addr)); } +/* ARGSUSED */ static int -vnic_ioc_modify(mblk_t *mp, int mode) +vnic_ioc_modify(void *karg, intptr_t arg, int mode, cred_t *cred) { - STRUCT_HANDLE(vnic_ioc_modify, modify_arg); - int err = 0; + vnic_ioc_modify_t *modify_arg = karg; datalink_id_t vnic_id; uint_t modify_mask; vnic_mac_addr_type_t mac_addr_type; uint_t mac_len; uchar_t mac_addr[MAXMACADDRLEN]; - STRUCT_SET_HANDLE(modify_arg, mode, (void *)mp->b_cont->b_rptr); - if (MBLKL(mp->b_cont) < STRUCT_SIZE(modify_arg)) - return (EINVAL); - - vnic_id = STRUCT_FGET(modify_arg, vm_vnic_id); - modify_mask = STRUCT_FGET(modify_arg, vm_modify_mask); + vnic_id = modify_arg->vm_vnic_id; + modify_mask = modify_arg->vm_modify_mask; if (modify_mask & VNIC_IOC_MODIFY_ADDR) { - mac_addr_type = STRUCT_FGET(modify_arg, vm_mac_addr_type); - mac_len = STRUCT_FGET(modify_arg, vm_mac_len); - bcopy(STRUCT_FGET(modify_arg, vm_mac_addr), mac_addr, - MAXMACADDRLEN); + mac_addr_type = modify_arg->vm_mac_addr_type; + mac_len = modify_arg->vm_mac_len; + bcopy(modify_arg->vm_mac_addr, mac_addr, MAXMACADDRLEN); } - err = vnic_dev_modify(vnic_id, modify_mask, mac_addr_type, - mac_len, mac_addr); - return (err); + return (vnic_dev_modify(vnic_id, modify_mask, mac_addr_type, + mac_len, mac_addr)); } +/* ARGSUSED */ static int -vnic_ioc_delete(mblk_t *mp, int mode) +vnic_ioc_delete(void *karg, intptr_t arg, int mode, cred_t *cred) { - STRUCT_HANDLE(vnic_ioc_delete, delete_arg); - datalink_id_t vnic_id; - int err = 0; + vnic_ioc_delete_t *delete_arg = karg; - STRUCT_SET_HANDLE(delete_arg, mode, (void *)mp->b_cont->b_rptr); - if (STRUCT_SIZE(delete_arg) > MBLKL(mp)) - return (EINVAL); - - vnic_id = STRUCT_FGET(delete_arg, vd_vnic_id); - err = vnic_dev_delete(vnic_id); - return (err); + return (vnic_dev_delete(delete_arg->vd_vnic_id)); } typedef struct vnic_ioc_info_state { - uint32_t bytes_left; - uchar_t *where; + uint32_t bytes_left; + uchar_t *where; + int mode; } vnic_ioc_info_state_t; static int @@ -461,7 +311,9 @@ vnic_ioc_info_new_vnic(void *arg, datalink_id_t id, vn->vn_link_id = linkid; vn->vn_mac_addr_type = addr_type; vn->vn_mac_len = mac_len; - bcopy(mac_addr, &(vn->vn_mac_addr), mac_len); + if (ddi_copyout(mac_addr, &(vn->vn_mac_addr), mac_len, + state->mode) != 0) + return (EFAULT); state->where += sizeof (*vn); state->bytes_left -= sizeof (*vn); @@ -471,20 +323,13 @@ vnic_ioc_info_new_vnic(void *arg, datalink_id_t id, /* ARGSUSED */ static int -vnic_ioc_info(mblk_t *mp, int mode) +vnic_ioc_info(void *karg, intptr_t arg, int mode, cred_t *cred) { - vnic_ioc_info_t *info_argp; - int rc, len; + vnic_ioc_info_t *info_argp = karg; uint32_t nvnics; datalink_id_t vnic_id, linkid; vnic_ioc_info_state_t state; - if ((len = MBLKL(mp->b_cont)) < sizeof (*info_argp)) - return (EINVAL); - - /* LINTED alignment */ - info_argp = (vnic_ioc_info_t *)mp->b_cont->b_rptr; - /* * ID of the vnic to return or vnic device. * If zero, the call returns information @@ -493,10 +338,10 @@ vnic_ioc_info(mblk_t *mp, int mode) vnic_id = info_argp->vi_vnic_id; linkid = info_argp->vi_linkid; - state.bytes_left = len - sizeof (vnic_ioc_info_t); - state.where = (uchar_t *)(info_argp +1); + state.bytes_left = info_argp->vi_size; + state.where = (uchar_t *)(arg + sizeof (vnic_ioc_info_t)); + state.mode = mode; - rc = vnic_info(&nvnics, vnic_id, linkid, &state, - vnic_ioc_info_new_vnic); - return (rc); + return (vnic_info(&nvnics, vnic_id, linkid, &state, + vnic_ioc_info_new_vnic)); } diff --git a/usr/src/uts/common/os/policy.c b/usr/src/uts/common/os/policy.c index 5d7eac6b1c..f814ffb4b1 100644 --- a/usr/src/uts/common/os/policy.c +++ b/usr/src/uts/common/os/policy.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/sysmacros.h> #include <sys/param.h> @@ -1702,6 +1700,18 @@ secpolicy_ip_config(const cred_t *cr, boolean_t checkonly) } } +/* + * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_DL_CONFIG. + */ +int +secpolicy_dl_config(const cred_t *cr) +{ + if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE)) + return (secpolicy_net_config(cr, B_FALSE)); + return (PRIV_POLICY(cr, PRIV_SYS_DL_CONFIG, B_FALSE, EPERM, + NULL)); +} + /* * Map IP pseudo privileges to actual privileges. diff --git a/usr/src/uts/common/os/priv_defs b/usr/src/uts/common/os/priv_defs index bd4866f926..82d93a5250 100644 --- a/usr/src/uts/common/os/priv_defs +++ b/usr/src/uts/common/os/priv_defs @@ -25,8 +25,6 @@ INSERT COMMENT */ -#pragma ident "%Z%%M% %I% %E% SMI" - # # Privileges can be added to this file at any location, not # necessarily at the end. For patches, it is probably best to @@ -373,9 +371,13 @@ privilege PRIV_SYS_MOUNT only control mounts performed from within said zone. Outside the global zone, the "nodevices" option is always forced. +privilege PRIV_SYS_DL_CONFIG + + Allows a process to configure a system's datalink interfaces. + privilege PRIV_SYS_IP_CONFIG - Allows a process to configure a system's network interfaces and routes. + Allows a process to configure a system's IP interfaces and routes. Allows a process to configure network parameters using ndd. Allows a process access to otherwise restricted information using ndd. Allows a process to configure IPsec. @@ -383,7 +385,7 @@ privilege PRIV_SYS_IP_CONFIG privilege PRIV_SYS_NET_CONFIG - Allows all that PRIV_SYS_IP_CONFIG allows. + Allows all that PRIV_SYS_IP_CONFIG and PRIV_SYS_DL_CONFIG allow. Allows a process to push the rpcmod STREAMs module. Allows a process to INSERT/REMOVE STREAMs modules on locations other than the top of the module stack. diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile index 0b827c3bde..510ba70ff3 100644 --- a/usr/src/uts/common/sys/Makefile +++ b/usr/src/uts/common/sys/Makefile @@ -185,6 +185,7 @@ CHKHDRS= \ dlpi.h \ dld.h \ dld_impl.h \ + dld_ioc.h \ dls.h \ dls_impl.h \ dma_i8237A.h \ diff --git a/usr/src/uts/common/sys/aggr.h b/usr/src/uts/common/sys/aggr.h index c89cca4d46..740ac7f6f9 100644 --- a/usr/src/uts/common/sys/aggr.h +++ b/usr/src/uts/common/sys/aggr.h @@ -26,20 +26,23 @@ #ifndef _SYS_AGGR_H #define _SYS_AGGR_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/ethernet.h> #include <sys/mac.h> #include <sys/dls.h> #include <sys/param.h> +#include <sys/dld_ioc.h> #ifdef __cplusplus extern "C" { #endif -/* control interface name */ -#define AGGR_DEVNAME_CTL "ctl" +/* + * Note that the datastructures defined here define an ioctl interface + * that is shared betwen user and kernel space. The aggr driver thus + * assumes that the structures have identical layout and size when + * compiled in either IPL32 or LP64. + */ /* * Transmit load balancing policies. @@ -112,14 +115,12 @@ typedef union { uint8_t state; } aggr_lacp_state_t; -#define LAIOC(x) (('l' << 24) | ('a' << 16) | ('m' << 8) | (x)) - /* one of the ports of a link aggregation group */ typedef struct laioc_port { datalink_id_t lp_linkid; } laioc_port_t; -#define LAIOC_CREATE LAIOC(1) +#define LAIOC_CREATE AGGRIOC(1) typedef struct laioc_create { datalink_id_t lc_linkid; @@ -134,38 +135,13 @@ typedef struct laioc_create { lc_pad_bits : 30; } laioc_create_t; -#ifdef _SYSCALL32 - -typedef struct laioc_create32 { - datalink_id_t lc_linkid; - uint32_t lc_key; - uint32_t lc_nports; - uint32_t lc_policy; - uchar_t lc_mac[ETHERADDRL]; - aggr_lacp_mode_t lc_lacp_mode; - aggr_lacp_timer_t lc_lacp_timer; - uint32_t lc_mac_fixed : 1, - lc_force : 1, - lc_pad_bits : 30; -} laioc_create32_t; - -#endif /* _SYSCALL32 */ - -#define LAIOC_DELETE LAIOC(2) +#define LAIOC_DELETE AGGRIOC(2) typedef struct laioc_delete { datalink_id_t ld_linkid; } laioc_delete_t; -#ifdef _SYSCALL32 - -typedef struct laioc_delete32 { - datalink_id_t ld_linkid; -} laioc_delete32_t; - -#endif /* _SYSCALL32 */ - -#define LAIOC_INFO LAIOC(3) +#define LAIOC_INFO AGGRIOC(3) typedef enum aggr_link_duplex { AGGR_LINK_DUPLEX_FULL = 1, @@ -201,10 +177,11 @@ typedef struct laioc_info_group { typedef struct laioc_info { /* Must not be DLADM_INVALID_LINKID */ datalink_id_t li_group_linkid; + uint32_t li_bufsize; } laioc_info_t; -#define LAIOC_ADD LAIOC(4) -#define LAIOC_REMOVE LAIOC(5) +#define LAIOC_ADD AGGRIOC(4) +#define LAIOC_REMOVE AGGRIOC(5) typedef struct laioc_add_rem { datalink_id_t la_linkid; @@ -212,17 +189,7 @@ typedef struct laioc_add_rem { uint32_t la_force; } laioc_add_rem_t; -#ifdef _SYSCALL32 - -typedef struct laioc_add_rem32 { - datalink_id_t la_linkid; - uint32_t la_nports; - uint32_t la_force; -} laioc_add_rem32_t; - -#endif /* _SYSCALL32 */ - -#define LAIOC_MODIFY LAIOC(6) +#define LAIOC_MODIFY AGGRIOC(6) #define LAIOC_MODIFY_POLICY 0x01 #define LAIOC_MODIFY_MAC 0x02 @@ -239,20 +206,6 @@ typedef struct laioc_modify { aggr_lacp_timer_t lu_lacp_timer; } laioc_modify_t; -#ifdef _SYSCALL32 - -typedef struct laioc_modify32 { - datalink_id_t lu_linkid; - uint8_t lu_modify_mask; - uint32_t lu_policy; - uchar_t lu_mac[ETHERADDRL]; - boolean_t lu_mac_fixed; - aggr_lacp_mode_t lu_lacp_mode; - aggr_lacp_timer_t lu_lacp_timer; -} laioc_modify32_t; - -#endif /* _SYSCALL32 */ - #ifdef __cplusplus } #endif diff --git a/usr/src/uts/common/sys/aggr_impl.h b/usr/src/uts/common/sys/aggr_impl.h index e9cd95acec..5fbbb54fe8 100644 --- a/usr/src/uts/common/sys/aggr_impl.h +++ b/usr/src/uts/common/sys/aggr_impl.h @@ -26,8 +26,6 @@ #ifndef _SYS_AGGR_IMPL_H #define _SYS_AGGR_IMPL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/mac.h> #include <sys/mac_ether.h> @@ -174,7 +172,8 @@ typedef struct aggr_grp_s { } extern dev_info_t *aggr_dip; -extern void aggr_ioctl(queue_t *, mblk_t *); +extern int aggr_ioc_init(void); +extern void aggr_ioc_fini(void); typedef int (*aggr_grp_info_new_grp_fn_t)(void *, datalink_id_t, uint32_t, uchar_t *, boolean_t, boolean_t, uint32_t, uint32_t, aggr_lacp_mode_t, diff --git a/usr/src/uts/common/sys/dld.h b/usr/src/uts/common/sys/dld.h index 1af906c90b..8d302abffb 100644 --- a/usr/src/uts/common/sys/dld.h +++ b/usr/src/uts/common/sys/dld.h @@ -28,10 +28,16 @@ /* * Data-Link Driver (public header). + * + * Note that the datastructures defined here define an ioctl interface + * that is shared betwen user and kernel space. The dld driver thus + * assumes that the structures have identical layout and size when + * compiled in either IPL32 or LP64. */ #include <sys/types.h> #include <sys/stream.h> +#include <sys/dld_ioc.h> #include <sys/conf.h> #include <sys/sad.h> #include <net/if.h> @@ -79,26 +85,16 @@ extern "C" { #define DLD_DRIVER_NAME "dld" /* - * The name of the control minor node of dld. - */ -#define DLD_CONTROL_MINOR_NAME "ctl" -#define DLD_CONTROL_MINOR 0 -#define DLD_CONTROL_DEV "/devices/pseudo/" DLD_DRIVER_NAME "@0:" \ - DLD_CONTROL_MINOR_NAME - -/* * IOCTL codes and data structures. */ -#define DLDIOC ('D' << 24 | 'L' << 16 | 'D' << 8) - -#define DLDIOC_ATTR (DLDIOC | 0x03) +#define DLDIOC_ATTR DLDIOC(0x03) typedef struct dld_ioc_attr { datalink_id_t dia_linkid; uint_t dia_max_sdu; } dld_ioc_attr_t; -#define DLDIOC_VLAN_ATTR (DLDIOC | 0x04) +#define DLDIOC_VLAN_ATTR DLDIOC(0x04) typedef struct dld_ioc_vlan_attr { datalink_id_t div_vlanid; uint16_t div_vid; @@ -107,7 +103,7 @@ typedef struct dld_ioc_vlan_attr { boolean_t div_implicit; } dld_ioc_vlan_attr_t; -#define DLDIOC_PHYS_ATTR (DLDIOC | 0x05) +#define DLDIOC_PHYS_ATTR DLDIOC(0x05) #define DLPI_LINKNAME_MAX 32 typedef struct dld_ioc_phys_attr { @@ -139,31 +135,32 @@ typedef struct dld_secobj { uint_t so_len; } dld_secobj_t; -#define DLDIOC_SECOBJ_SET (DLDIOC | 0x06) +#define DLDIOC_SECOBJ_SET DLDIOC(0x06) typedef struct dld_ioc_secobj_set { dld_secobj_t ss_obj; uint_t ss_flags; } dld_ioc_secobj_set_t; -#define DLDIOC_SECOBJ_GET (DLDIOC | 0x07) +#define DLDIOC_SECOBJ_GET DLDIOC(0x07) typedef struct dld_ioc_secobj_get { dld_secobj_t sg_obj; uint_t sg_count; + uint_t sg_size; } dld_ioc_secobj_get_t; /* * The following two slots were used outside of ON, so don't reuse them. * - * #define DLDIOCHOLDVLAN (DLDIOC | 0x08) - * #define DLDIOCRELEVLAN (DLDIOC | 0x09) + * #define DLDIOCHOLDVLAN DLDIOC(0x08) + * #define DLDIOCRELEVLAN DLDIOC(0x09) */ -#define DLDIOC_SECOBJ_UNSET (DLDIOC | 0x0a) +#define DLDIOC_SECOBJ_UNSET DLDIOC(0x0a) typedef struct dld_ioc_secobj_unset { char su_name[DLD_SECOBJ_NAME_MAX]; } dld_ioc_secobj_unset_t; -#define DLDIOC_CREATE_VLAN (DLDIOC | 0x0b) +#define DLDIOC_CREATE_VLAN DLDIOC(0x0b) typedef struct dld_ioc_create_vlan { datalink_id_t dic_vlanid; datalink_id_t dic_linkid; @@ -171,7 +168,7 @@ typedef struct dld_ioc_create_vlan { boolean_t dic_force; } dld_ioc_create_vlan_t; -#define DLDIOC_DELETE_VLAN (DLDIOC | 0x0c) +#define DLDIOC_DELETE_VLAN DLDIOC(0x0c) typedef struct dld_ioc_delete_vlan { datalink_id_t did_linkid; } dld_ioc_delete_vlan_t; @@ -179,17 +176,17 @@ typedef struct dld_ioc_delete_vlan { /* * 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_SETAUTOPUSH DLDIOC(0x0d) + * #define DLDIOC_GETAUTOPUSH DLDIOC(0x0e) + * #define DLDIOC_CLRAUTOPUSH DLDIOC(0x0f) */ -#define DLDIOC_DOORSERVER (DLDIOC | 0x10) +#define DLDIOC_DOORSERVER DLDIOC(0x10) typedef struct dld_ioc_door { boolean_t did_start_door; } dld_ioc_door_t; -#define DLDIOC_RENAME (DLDIOC | 0x11) +#define DLDIOC_RENAME DLDIOC(0x11) typedef struct dld_ioc_rename { datalink_id_t dir_linkid1; datalink_id_t dir_linkid2; @@ -199,8 +196,8 @@ typedef struct dld_ioc_rename { /* * 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) + * #define DLDIOC_GETZID DLDIOC(0x13) */ typedef struct dld_ioc_zid { @@ -209,6 +206,12 @@ typedef struct dld_ioc_zid { boolean_t diz_is_ppa_hack; } dld_ioc_zid_t; +#define DLDIOC_GETZID DLDIOC(0x13) +typedef struct dld_ioc_getzid { + datalink_id_t dig_linkid; + zoneid_t dig_zid; +} dld_ioc_getzid_t; + /* * data-link autopush configuration. */ @@ -218,10 +221,8 @@ struct dlautopush { char dap_aplist[MAXAPUSH][FMNAMESZ+1]; }; - - -#define DLDIOC_SETMACPROP (DLDIOC | 0x14) -#define DLDIOC_GETMACPROP (DLDIOC | 0x15) +#define DLDIOC_SETMACPROP DLDIOC(0x14) +#define DLDIOC_GETMACPROP DLDIOC(0x15) #define MAC_PROP_VERSION 1 typedef struct dld_ioc_macprop_s { diff --git a/usr/src/uts/common/sys/dld_impl.h b/usr/src/uts/common/sys/dld_impl.h index f100561a19..8d2138cc52 100644 --- a/usr/src/uts/common/sys/dld_impl.h +++ b/usr/src/uts/common/sys/dld_impl.h @@ -39,6 +39,9 @@ extern "C" { #endif +#define DLD_CONTROL_MINOR_NAME "ctl" +#define DLD_CONTROL_MINOR 0 + #define DLD_CONTROL 0x00000001 #define DLD_DLPI 0x00000002 diff --git a/usr/src/uts/common/sys/dld_ioc.h b/usr/src/uts/common/sys/dld_ioc.h new file mode 100644 index 0000000000..cb8f5bf225 --- /dev/null +++ b/usr/src/uts/common/sys/dld_ioc.h @@ -0,0 +1,104 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_DLD_IOC_H +#define _SYS_DLD_IOC_H + +#include <sys/types.h> +#include <sys/cred.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The name of the dld control device. All GLDv3 control ioctls are + * performed on this device. + */ +#define DLD_CONTROL_DEV "/dev/dld" + +/* + * GLDv3 ioctl values are structured as follows: + * + * | 16-bits | 16-bits | + * +----------------+----------------+ + * | module-id | command-id | + * +----------------+----------------+ + */ +#define DLD_IOC_CMD(modid, cmdid) (((uint_t)(modid) << 16) | (cmdid)) +#define DLD_IOC_MODID(cmd) (((cmd) & 0xffff0000) >> 16) +/* + * GLDv3 module ids to be passed in as the first argument to + * dld_ioc_register() and dld_ioc_unregister(). + */ +#define DLD_IOC 0x0D1D +#define AGGR_IOC 0x0A66 +#define VNIC_IOC 0x0171 + +/* GLDv3 modules use these macros to generate unique ioctl commands */ +#define DLDIOC(cmdid) DLD_IOC_CMD(DLD_IOC, (cmdid)) +#define AGGRIOC(cmdid) DLD_IOC_CMD(AGGR_IOC, (cmdid)) +#define VNICIOC(cmdid) DLD_IOC_CMD(VNIC_IOC, (cmdid)) + +#ifdef _KERNEL + +/* + * GLDv3 modules register the ioctls they're interested in by passing + * in an array of dld_ioc_info_t to dld_ioc_register(). Modules + * should call dld_ioc_register() either in _init() or attach(). The + * dld module assumes that ddi_hold_devi_by_instance(<module>, 0, 0) + * will cause the module to load and call dld_ioc_register(). + * + * The di_cmd field is an ioctl command generated using one of the + * macros above. The di_argsize value is used by dld to copyin or + * copyout the correct amount of data depending on whether the + * DLDCOPYIN or DLDCOPYOUT flags are set so that every di_func() + * callback function does not need to copyin/out its own data. + */ +typedef int (dld_ioc_func_t)(void *, intptr_t, int, cred_t *); +typedef struct dld_ioc_info { + uint_t di_cmd; + uint_t di_flags; + size_t di_argsize; + dld_ioc_func_t *di_func; +} dld_ioc_info_t; + +/* Values for di_flags */ +#define DLDCOPYIN 0x00000001 /* copyin di_argsize amount of data */ +#define DLDCOPYOUT 0x00000002 /* copyout di_argsize amount of data */ +#define DLDDLCONFIG 0x00000004 /* ioctl requires PRIV_SYS_DL_CONFIG */ +#define DLDCOPYINOUT (DLDCOPYIN | DLDCOPYOUT) + +#define DLDIOCCNT(l) (sizeof (l) / sizeof (dld_ioc_info_t)) +int dld_ioc_register(uint16_t, dld_ioc_info_t *, uint_t); +void dld_ioc_unregister(uint16_t); + +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_DLD_IOC_H */ diff --git a/usr/src/uts/common/sys/policy.h b/usr/src/uts/common/sys/policy.h index fb8d502588..4d2562240a 100644 --- a/usr/src/uts/common/sys/policy.h +++ b/usr/src/uts/common/sys/policy.h @@ -26,8 +26,6 @@ #ifndef _SYS_POLICY_H #define _SYS_POLICY_H -#pragma ident "%Z%%M% %I% %E% SMI" /* TSOL 8 */ - #include <sys/types.h> #include <sys/cred.h> #include <sys/vnode.h> @@ -101,6 +99,7 @@ int secpolicy_fs_quota(const cred_t *, const struct vfs *); int secpolicy_idmap(const cred_t *); int secpolicy_ip(const cred_t *, int, boolean_t); int secpolicy_ip_config(const cred_t *, boolean_t); +int secpolicy_dl_config(const cred_t *); int secpolicy_ipc_access(const cred_t *, const struct kipc_perm *, mode_t); int secpolicy_ipc_config(const cred_t *); int secpolicy_ipc_owner(const cred_t *, const struct kipc_perm *); diff --git a/usr/src/uts/common/sys/vnic.h b/usr/src/uts/common/sys/vnic.h index 58622037b3..d17da6bf44 100644 --- a/usr/src/uts/common/sys/vnic.h +++ b/usr/src/uts/common/sys/vnic.h @@ -26,22 +26,22 @@ #ifndef _SYS_VNIC_H #define _SYS_VNIC_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/ethernet.h> #include <sys/param.h> #include <sys/mac.h> +#include <sys/dld_ioc.h> #ifdef __cplusplus extern "C" { #endif -/* control interface name */ -#define VNIC_CTL_NODE_NAME "ctl" -#define VNIC_CTL_NODE_MINOR 1 /* control interface minor */ - -#define VNIC_IOC(x) (('v' << 24) | ('n' << 16) | ('i' << 8) | (x)) +/* + * Note that the datastructures defined here define an ioctl interface + * that is shared betwen user and kernel space. The vnic driver thus + * assumes that the structures have identical layout and size when + * compiled in either IPL32 or LP64. + */ /* * For now, we support only MAC addresses specified by value. @@ -51,7 +51,7 @@ typedef enum { VNIC_MAC_ADDR_TYPE_FIXED } vnic_mac_addr_type_t; -#define VNIC_IOC_CREATE VNIC_IOC(1) +#define VNIC_IOC_CREATE VNICIOC(1) typedef struct vnic_ioc_create { datalink_id_t vc_vnic_id; @@ -61,33 +61,13 @@ typedef struct vnic_ioc_create { uchar_t vc_mac_addr[MAXMACADDRLEN]; } vnic_ioc_create_t; -#ifdef _SYSCALL32 - -typedef struct vnic_ioc_create32 { - datalink_id_t vc_vnic_id; - datalink_id_t vc_link_id; - uint32_t vc_mac_len; - vnic_mac_addr_type_t vc_mac_addr_type; - uchar_t vc_mac_addr[MAXMACADDRLEN]; -} vnic_ioc_create32_t; - -#endif /* _SYSCALL32 */ - -#define VNIC_IOC_DELETE VNIC_IOC(2) +#define VNIC_IOC_DELETE VNICIOC(2) typedef struct vnic_ioc_delete { datalink_id_t vd_vnic_id; } vnic_ioc_delete_t; -#ifdef _SYSCALL32 - -typedef struct vnic_ioc_delete32 { - datalink_id_t vd_vnic_id; -} vnic_ioc_delete32_t; - -#endif /* _SYSCALL32 */ - -#define VNIC_IOC_INFO VNIC_IOC(3) +#define VNIC_IOC_INFO VNICIOC(3) typedef struct vnic_ioc_info_vnic { datalink_id_t vn_vnic_id; @@ -99,21 +79,12 @@ typedef struct vnic_ioc_info_vnic { typedef struct vnic_ioc_info { uint_t vi_nvnics; + uint_t vi_size; datalink_id_t vi_vnic_id; /* DATALINK_ALL_LINKID returns all */ datalink_id_t vi_linkid; } vnic_ioc_info_t; -#ifdef _SYSCALL32 - -typedef struct vnic_ioc_info32 { - uint32_t vi_nvnics; - datalink_id_t vi_vnic_id; /* DATALINK_ALL_LINKID returns all */ - datalink_id_t vi_linkid; -} vnic_ioc_info32_t; - -#endif /* _SYSCALL32 */ - -#define VNIC_IOC_MODIFY VNIC_IOC(4) +#define VNIC_IOC_MODIFY VNICIOC(4) #define VNIC_IOC_MODIFY_ADDR 0x01 @@ -125,18 +96,6 @@ typedef struct vnic_ioc_modify { uint_t vm_mac_len; } vnic_ioc_modify_t; -#ifdef _SYSCALL32 - -typedef struct vnic_ioc_modify32 { - datalink_id_t vm_vnic_id; - uint32_t vm_modify_mask; - uchar_t vm_mac_addr[MAXMACADDRLEN]; - vnic_mac_addr_type_t vm_mac_addr_type; - uint32_t vm_mac_len; -} vnic_ioc_modify32_t; - -#endif /* _SYSCALL32 */ - #ifdef __cplusplus } #endif diff --git a/usr/src/uts/intel/os/device_policy b/usr/src/uts/intel/os/device_policy index 118fae1eaf..132881289b 100644 --- a/usr/src/uts/intel/os/device_policy +++ b/usr/src/uts/intel/os/device_policy @@ -21,8 +21,6 @@ # # CDDL HEADER END # -#ident "%Z%%M% %I% %E% SMI" -# # Device policy configuration file. When devices are opened the # additional access controls in this file are enforced. # @@ -78,9 +76,6 @@ scsi_vhci:devctl write_priv_set=sys_devices # random write_priv_set=sys_devices openeepr write_priv_set=all -dld:ctl read_priv_set=sys_net_config write_priv_set=sys_net_config -aggr:ctl read_priv_set=sys_net_config write_priv_set=sys_net_config -vnic:ctl read_priv_set=sys_net_config write_priv_set=sys_net_config # # IP Filter # diff --git a/usr/src/uts/sparc/os/device_policy b/usr/src/uts/sparc/os/device_policy index 2667ba50b3..25da20334d 100644 --- a/usr/src/uts/sparc/os/device_policy +++ b/usr/src/uts/sparc/os/device_policy @@ -21,8 +21,6 @@ # # CDDL HEADER END # -#ident "%Z%%M% %I% %E% SMI" -# # Device policy configuration file. When devices are opened the # additional access controls in this file are enforced. # @@ -82,9 +80,6 @@ scsi_vhci:devctl write_priv_set=sys_devices envctrltwo read_priv_set=sys_config write_priv_set=sys_config random write_priv_set=sys_devices openeepr write_priv_set=all -dld:ctl read_priv_set=sys_net_config write_priv_set=sys_net_config -aggr:ctl read_priv_set=sys_net_config write_priv_set=sys_net_config -vnic:ctl read_priv_set=sys_net_config write_priv_set=sys_net_config # # IP Filter # |