dld_drv.c (afdda45f) dld_drv.c (da14cebe)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 17 unchanged lines hidden (view full) ---

26/*
27 * Data-Link Driver
28 */
29
30#include <sys/conf.h>
31#include <sys/mkdev.h>
32#include <sys/modctl.h>
33#include <sys/stat.h>
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 17 unchanged lines hidden (view full) ---

26/*
27 * Data-Link Driver
28 */
29
30#include <sys/conf.h>
31#include <sys/mkdev.h>
32#include <sys/modctl.h>
33#include <sys/stat.h>
34#include <sys/vlan.h>
35#include <sys/mac.h>
36#include <sys/dld_impl.h>
37#include <sys/dls_impl.h>
38#include <sys/softmac.h>
34#include <sys/dld_impl.h>
35#include <sys/dls_impl.h>
36#include <sys/softmac.h>
39#include <sys/vlan.h>
40#include <sys/policy.h>
37#include <sys/mac.h>
38#include <sys/mac_ether.h>
39#include <sys/mac_client.h>
40#include <sys/mac_client_impl.h>
41#include <sys/mac_client_priv.h>
41#include <inet/common.h>
42#include <inet/common.h>
43#include <sys/policy.h>
44#include <sys/priv_names.h>
42
43static void drv_init(void);
44static int drv_fini(void);
45
46static int drv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
47static int drv_attach(dev_info_t *, ddi_attach_cmd_t);
48static int drv_detach(dev_info_t *, ddi_detach_cmd_t);
49

--- 95 unchanged lines hidden (view full) ---

145/*
146 * Initialize component modules.
147 */
148static void
149drv_init(void)
150{
151 drv_secobj_init();
152 dld_str_init();
45
46static void drv_init(void);
47static int drv_fini(void);
48
49static int drv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
50static int drv_attach(dev_info_t *, ddi_attach_cmd_t);
51static int drv_detach(dev_info_t *, ddi_detach_cmd_t);
52

--- 95 unchanged lines hidden (view full) ---

148/*
149 * Initialize component modules.
150 */
151static void
152drv_init(void)
153{
154 drv_secobj_init();
155 dld_str_init();
156
153 /*
154 * Create a hash table for autopush configuration.
155 */
156 dld_ap_hashp = mod_hash_create_idhash("dld_autopush_hash",
157 NAUTOPUSH, mod_hash_null_valdtor);
158
159 ASSERT(dld_ap_hashp != NULL);
160 rw_init(&dld_ap_hash_lock, NULL, RW_DRIVER, NULL);

--- 13 unchanged lines hidden (view full) ---

174drv_fini(void)
175{
176 int err;
177 boolean_t exist = B_FALSE;
178
179 rw_enter(&dld_ap_hash_lock, RW_READER);
180 mod_hash_walk(dld_ap_hashp, drv_ap_exist, &exist);
181 rw_exit(&dld_ap_hash_lock);
157 /*
158 * Create a hash table for autopush configuration.
159 */
160 dld_ap_hashp = mod_hash_create_idhash("dld_autopush_hash",
161 NAUTOPUSH, mod_hash_null_valdtor);
162
163 ASSERT(dld_ap_hashp != NULL);
164 rw_init(&dld_ap_hash_lock, NULL, RW_DRIVER, NULL);

--- 13 unchanged lines hidden (view full) ---

178drv_fini(void)
179{
180 int err;
181 boolean_t exist = B_FALSE;
182
183 rw_enter(&dld_ap_hash_lock, RW_READER);
184 mod_hash_walk(dld_ap_hashp, drv_ap_exist, &exist);
185 rw_exit(&dld_ap_hash_lock);
182
183 if (exist)
184 return (EBUSY);
185
186 if ((err = dld_str_fini()) != 0)
187 return (err);
188
189 drv_secobj_fini();
190 mod_hash_destroy_idhash(dld_ap_hashp);

--- 118 unchanged lines hidden (view full) ---

309 return (0);
310}
311
312/*
313 * DLDIOC_ATTR
314 */
315/* ARGSUSED */
316static int
186 if (exist)
187 return (EBUSY);
188
189 if ((err = dld_str_fini()) != 0)
190 return (err);
191
192 drv_secobj_fini();
193 mod_hash_destroy_idhash(dld_ap_hashp);

--- 118 unchanged lines hidden (view full) ---

312 return (0);
313}
314
315/*
316 * DLDIOC_ATTR
317 */
318/* ARGSUSED */
319static int
317drv_ioc_attr(void *karg, intptr_t arg, int mode, cred_t *cred)
320drv_ioc_attr(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
318{
319 dld_ioc_attr_t *diap = karg;
320 dls_dl_handle_t dlh;
321{
322 dld_ioc_attr_t *diap = karg;
323 dls_dl_handle_t dlh;
321 dls_vlan_t *dvp;
324 dls_link_t *dlp;
322 int err;
325 int err;
326 mac_perim_handle_t mph;
323
324 if ((err = dls_devnet_hold_tmp(diap->dia_linkid, &dlh)) != 0)
325 return (err);
326
327
328 if ((err = dls_devnet_hold_tmp(diap->dia_linkid, &dlh)) != 0)
329 return (err);
330
327 if ((err = dls_vlan_hold(dls_devnet_mac(dlh),
328 dls_devnet_vid(dlh), &dvp, B_FALSE, B_FALSE)) != 0) {
331 if ((err = mac_perim_enter_by_macname(
332 dls_devnet_mac(dlh), &mph)) != 0) {
329 dls_devnet_rele_tmp(dlh);
330 return (err);
331 }
333 dls_devnet_rele_tmp(dlh);
334 return (err);
335 }
332 mac_sdu_get(dvp->dv_dlp->dl_mh, NULL, &diap->dia_max_sdu);
333
336
334 dls_vlan_rele(dvp);
337 if ((err = dls_link_hold(dls_devnet_mac(dlh), &dlp)) != 0) {
338 mac_perim_exit(mph);
339 dls_devnet_rele_tmp(dlh);
340 return (err);
341 }
342
343 mac_sdu_get(dlp->dl_mh, NULL, &diap->dia_max_sdu);
344
345 dls_link_rele(dlp);
346 mac_perim_exit(mph);
335 dls_devnet_rele_tmp(dlh);
336
337 return (0);
338}
339
340/*
341 * DLDIOC_PHYS_ATTR
342 */
343/* ARGSUSED */
344static int
347 dls_devnet_rele_tmp(dlh);
348
349 return (0);
350}
351
352/*
353 * DLDIOC_PHYS_ATTR
354 */
355/* ARGSUSED */
356static int
345drv_ioc_phys_attr(void *karg, intptr_t arg, int mode, cred_t *cred)
357drv_ioc_phys_attr(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
346{
347 dld_ioc_phys_attr_t *dipp = karg;
348 int err;
349 dls_dl_handle_t dlh;
350 dls_dev_handle_t ddh;
351 dev_t phydev;
352
353 /*

--- 28 unchanged lines hidden (view full) ---

382 */
383 (void) snprintf(dipp->dip_dev, MAXLINKNAMELEN, "%s%d",
384 ddi_major_to_name(getmajor(phydev)), getminor(phydev) - 1);
385
386 softmac_rele_device(ddh);
387 return (0);
388}
389
358{
359 dld_ioc_phys_attr_t *dipp = karg;
360 int err;
361 dls_dl_handle_t dlh;
362 dls_dev_handle_t ddh;
363 dev_t phydev;
364
365 /*

--- 28 unchanged lines hidden (view full) ---

394 */
395 (void) snprintf(dipp->dip_dev, MAXLINKNAMELEN, "%s%d",
396 ddi_major_to_name(getmajor(phydev)), getminor(phydev) - 1);
397
398 softmac_rele_device(ddh);
399 return (0);
400}
401
402/* ARGSUSED */
403static int
404drv_ioc_hwgrpget(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
405{
406 dld_ioc_hwgrpget_t *hwgrpp = karg;
407 dld_hwgrpinfo_t hwgrp, *hip;
408 mac_handle_t mh = NULL;
409 int i, err, grpnum;
410 uint_t bytes_left;
411
412 hwgrpp->dih_n_groups = 0;
413 err = mac_open_by_linkid(hwgrpp->dih_linkid, &mh);
414 if (err != 0)
415 goto done;
416
417 hip = (dld_hwgrpinfo_t *)
418 ((uchar_t *)arg + sizeof (dld_ioc_hwgrpget_t));
419 bytes_left = hwgrpp->dih_size;
420 grpnum = mac_hwgrp_num(mh);
421 for (i = 0; i < grpnum; i++) {
422 if (sizeof (dld_hwgrpinfo_t) > bytes_left) {
423 err = ENOSPC;
424 goto done;
425 }
426
427 bzero(&hwgrp, sizeof (hwgrp));
428 bcopy(mac_name(mh), hwgrp.dhi_link_name,
429 sizeof (hwgrp.dhi_link_name));
430 mac_get_hwgrp_info(mh, i, &hwgrp.dhi_grp_num,
431 &hwgrp.dhi_n_rings, &hwgrp.dhi_grp_type,
432 &hwgrp.dhi_n_clnts, hwgrp.dhi_clnts);
433 if (copyout(&hwgrp, hip, sizeof (hwgrp)) != 0) {
434 err = EFAULT;
435 goto done;
436 }
437
438 hip++;
439 bytes_left -= sizeof (dld_hwgrpinfo_t);
440 }
441
442done:
443 if (mh != NULL)
444 dld_mac_close(mh);
445 if (err == 0)
446 hwgrpp->dih_n_groups = grpnum;
447 return (err);
448}
449
450/* ARGSUSED */
451static int
452drv_ioc_macaddrget(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
453{
454 dld_ioc_macaddrget_t *magp = karg;
455 dld_macaddrinfo_t mai, *maip;
456 mac_handle_t mh = NULL;
457 int i, err;
458 uint_t bytes_left;
459 boolean_t is_used;
460
461 magp->dig_count = 0;
462 err = mac_open_by_linkid(magp->dig_linkid, &mh);
463 if (err != 0)
464 goto done;
465
466 maip = (dld_macaddrinfo_t *)
467 ((uchar_t *)arg + sizeof (dld_ioc_macaddrget_t));
468 bytes_left = magp->dig_size;
469
470 for (i = 0; i < mac_addr_factory_num(mh) + 1; i++) {
471 if (sizeof (dld_macaddrinfo_t) > bytes_left) {
472 err = ENOSPC;
473 goto done;
474 }
475
476 bzero(&mai, sizeof (mai));
477
478 if (i == 0) {
479 /* primary MAC address */
480 mac_unicast_primary_get(mh, mai.dmi_addr);
481 mai.dmi_addrlen = mac_addr_len(mh);
482 mac_unicast_primary_info(mh, mai.dmi_client_name,
483 &is_used);
484 } else {
485 /* factory MAC address slot */
486 mac_addr_factory_value(mh, i, mai.dmi_addr,
487 &mai.dmi_addrlen, mai.dmi_client_name, &is_used);
488 }
489
490 mai.dmi_slot = i;
491 if (is_used)
492 mai.dmi_flags |= DLDIOCMACADDR_USED;
493
494 if (copyout(&mai, maip, sizeof (mai)) != 0) {
495 err = EFAULT;
496 goto done;
497 }
498
499 maip++;
500 bytes_left -= sizeof (dld_macaddrinfo_t);
501 }
502
503done:
504 if (mh != NULL)
505 dld_mac_close(mh);
506 if (err == 0)
507 magp->dig_count = mac_addr_factory_num(mh) + 1;
508 return (err);
509}
510
390/*
511/*
391 * DLDIOC_SETPROP
512 * DLDIOC_SET/GETPROP
392 */
393static int
513 */
514static int
394drv_ioc_prop_common(dld_ioc_macprop_t *dipp, intptr_t arg, boolean_t set,
515drv_ioc_prop_common(dld_ioc_macprop_t *prop, intptr_t arg, boolean_t set,
395 int mode)
396{
516 int mode)
517{
397 int err = EINVAL;
398 size_t dsize;
399 dld_ioc_macprop_t *kdipp;
400 dls_dl_handle_t dlh;
401 dls_vlan_t *dvp;
402 datalink_id_t linkid;
518 int err = EINVAL;
519 dls_dl_handle_t dlh = NULL;
520 dls_link_t *dlp = NULL;
521 mac_perim_handle_t mph = NULL;
403 mac_prop_t macprop;
522 mac_prop_t macprop;
404 uchar_t *cp;
405 struct dlautopush *dlap;
406 dld_ioc_zid_t *dzp;
523 dld_ioc_macprop_t *kprop;
524 datalink_id_t linkid;
525 uint_t dsize;
407
526
527
408 /*
528 /*
409 * We only use pr_valsize from dipp, as the caller only did a
529 * We only use pr_valsize from prop, as the caller only did a
410 * copyin() for sizeof (dld_ioc_prop_t), which doesn't cover
411 * the property data. We copyin the full dld_ioc_prop_t
530 * copyin() for sizeof (dld_ioc_prop_t), which doesn't cover
531 * the property data. We copyin the full dld_ioc_prop_t
412 * including the data into kdipp down below.
532 * including the data into kprop down below.
413 */
533 */
414 dsize = sizeof (dld_ioc_macprop_t) + dipp->pr_valsize - 1;
415 if (dsize < dipp->pr_valsize)
534 dsize = sizeof (dld_ioc_macprop_t) + prop->pr_valsize - 1;
535 if (dsize < prop->pr_valsize)
416 return (EINVAL);
417
418 /*
419 * The property data is variable size, so we need to allocate
420 * a buffer for kernel use as this data was not part of the
536 return (EINVAL);
537
538 /*
539 * The property data is variable size, so we need to allocate
540 * a buffer for kernel use as this data was not part of the
421 * dipp allocation and copyin() done by the framework.
541 * prop allocation and copyin() done by the framework.
422 */
542 */
423 if ((kdipp = kmem_alloc(dsize, KM_NOSLEEP)) == NULL)
543 if ((kprop = kmem_alloc(dsize, KM_NOSLEEP)) == NULL)
424 return (ENOMEM);
544 return (ENOMEM);
425 if (ddi_copyin((void *)arg, kdipp, dsize, mode) != 0) {
545
546 if (ddi_copyin((void *)arg, kprop, dsize, mode) != 0) {
426 err = EFAULT;
427 goto done;
428 }
429
547 err = EFAULT;
548 goto done;
549 }
550
430 linkid = kdipp->pr_linkid;
551 linkid = kprop->pr_linkid;
552 if ((err = dls_devnet_hold_tmp(linkid, &dlh)) != 0)
553 goto done;
431
554
432 switch (dipp->pr_num) {
433 case MAC_PROP_ZONE:
555 if ((err = mac_perim_enter_by_macname(dls_devnet_mac(dlh),
556 &mph)) != 0) {
557 goto done;
558 }
559
560 switch (kprop->pr_num) {
561 case MAC_PROP_ZONE: {
434 if (set) {
562 if (set) {
435 dzp = (dld_ioc_zid_t *)kdipp->pr_val;
563 dld_ioc_zid_t *dzp = (dld_ioc_zid_t *)kprop->pr_val;
564
436 err = dls_devnet_setzid(dzp->diz_link, dzp->diz_zid);
437 goto done;
438 } else {
565 err = dls_devnet_setzid(dzp->diz_link, dzp->diz_zid);
566 goto done;
567 } else {
439 kdipp->pr_perm_flags = MAC_PROP_PERM_RW;
440 cp = (uchar_t *)kdipp->pr_val;
441 err = dls_devnet_getzid(linkid, (zoneid_t *)cp);
568 kprop->pr_perm_flags = MAC_PROP_PERM_RW;
569 err = dls_devnet_getzid(linkid,
570 (zoneid_t *)kprop->pr_val);
442 goto done;
443 }
571 goto done;
572 }
444 case MAC_PROP_AUTOPUSH:
573 }
574 case MAC_PROP_AUTOPUSH: {
575 struct dlautopush *dlap =
576 (struct dlautopush *)kprop->pr_val;
577
445 if (set) {
578 if (set) {
446 if (dipp->pr_valsize != 0) {
447 dlap = (struct dlautopush *)kdipp->pr_val;
579 if (kprop->pr_valsize != 0) {
448 err = drv_ioc_setap(linkid, dlap);
449 goto done;
450 } else {
451 err = drv_ioc_clrap(linkid);
452 goto done;
453 }
454 } else {
580 err = drv_ioc_setap(linkid, dlap);
581 goto done;
582 } else {
583 err = drv_ioc_clrap(linkid);
584 goto done;
585 }
586 } else {
455 kdipp->pr_perm_flags = MAC_PROP_PERM_RW;
456 dlap = (struct dlautopush *)kdipp->pr_val;
587 kprop->pr_perm_flags = MAC_PROP_PERM_RW;
457 err = drv_ioc_getap(linkid, dlap);
458 goto done;
459 }
588 err = drv_ioc_getap(linkid, dlap);
589 goto done;
590 }
460
591 }
461 default:
462 break;
463 }
464
592 default:
593 break;
594 }
595
465 if ((err = dls_devnet_hold_tmp(linkid, &dlh)) != 0)
596 if ((err = dls_link_hold(dls_devnet_mac(dlh), &dlp)) != 0)
466 goto done;
467
597 goto done;
598
468 if ((err = dls_vlan_hold(dls_devnet_mac(dlh),
469 dls_devnet_vid(dlh), &dvp, B_FALSE, B_FALSE)) != 0) {
470 dls_devnet_rele_tmp(dlh);
471 goto done;
472 }
599 macprop.mp_name = kprop->pr_name;
600 macprop.mp_id = kprop->pr_num;
601 macprop.mp_flags = kprop->pr_flags;
473
602
474 macprop.mp_name = kdipp->pr_name;
475 macprop.mp_id = kdipp->pr_num;
476 macprop.mp_flags = kdipp->pr_flags;
477
478 if (set) {
603 if (set) {
479 err = mac_set_prop(dvp->dv_dlp->dl_mh, &macprop,
480 kdipp->pr_val, kdipp->pr_valsize);
604 err = mac_set_prop(dlp->dl_mh, &macprop, kprop->pr_val,
605 kprop->pr_valsize);
481 } else {
606 } else {
482 kdipp->pr_perm_flags = MAC_PROP_PERM_RW;
483 err = mac_get_prop(dvp->dv_dlp->dl_mh, &macprop,
484 kdipp->pr_val, kdipp->pr_valsize, &kdipp->pr_perm_flags);
607 kprop->pr_perm_flags = MAC_PROP_PERM_RW;
608 err = mac_get_prop(dlp->dl_mh, &macprop, kprop->pr_val,
609 kprop->pr_valsize, &kprop->pr_perm_flags);
485 }
486
610 }
611
487 dls_vlan_rele(dvp);
488 dls_devnet_rele_tmp(dlh);
489done:
490 if (!set && err == 0 &&
612done:
613 if (!set && err == 0 &&
491 ddi_copyout(kdipp, (void *)arg, dsize, mode) != 0)
614 ddi_copyout(kprop, (void *)arg, dsize, mode) != 0)
492 err = EFAULT;
615 err = EFAULT;
493 kmem_free(kdipp, dsize);
494 return (err);
495}
496
616
497/* ARGSUSED */
498static int
499drv_ioc_setprop(void *karg, intptr_t arg, int mode, cred_t *cred)
500{
501 return (drv_ioc_prop_common(karg, arg, B_TRUE, mode));
502}
617 if (dlp != NULL)
618 dls_link_rele(dlp);
503
619
504/* ARGSUSED */
505static int
506drv_ioc_getprop(void *karg, intptr_t arg, int mode, cred_t *cred)
507{
508 return (drv_ioc_prop_common(karg, arg, B_FALSE, mode));
509}
620 if (mph != NULL) {
621 int32_t cpuid;
622 void *mdip = NULL;
510
623
511/*
512 * DLDIOC_CREATE_VLAN
513 */
514/* ARGSUSED */
515static int
516drv_ioc_create_vlan(void *karg, intptr_t arg, int mode, cred_t *cred)
517{
518 dld_ioc_create_vlan_t *dicp = karg;
624 if (dlp != NULL && set && err == 0) {
625 cpuid = mac_client_intr_cpu(dlp->dl_mch);
626 mdip = mac_get_devinfo(dlp->dl_mh);
627 }
519
628
520 return (dls_devnet_create_vlan(dicp->dic_vlanid, dicp->dic_linkid,
521 dicp->dic_vid, dicp->dic_force));
629 mac_perim_exit(mph);
630
631 if (mdip != NULL)
632 mac_client_set_intr_cpu(mdip, dlp->dl_mch, cpuid);
633 }
634 if (dlh != NULL)
635 dls_devnet_rele_tmp(dlh);
636
637 if (kprop != NULL)
638 kmem_free(kprop, dsize);
639 return (err);
522}
523
640}
641
524/*
525 * DLDIOC_DELETE_VLAN
526 */
527/* ARGSUSED */
528static int
642/* ARGSUSED */
643static int
529drv_ioc_delete_vlan(void *karg, intptr_t arg, int mode, cred_t *cred)
644drv_ioc_setprop(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
530{
645{
531 dld_ioc_delete_vlan_t *didp = karg;
532
533 return (dls_devnet_destroy_vlan(didp->did_linkid));
646 return (drv_ioc_prop_common(karg, arg, B_TRUE, mode));
534}
535
647}
648
536/*
537 * DLDIOC_VLAN_ATTR
538 */
539/* ARGSUSED */
540static int
649/* ARGSUSED */
650static int
541drv_ioc_vlan_attr(void *karg, intptr_t arg, int mode, cred_t *cred)
651drv_ioc_getprop(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
542{
652{
543 dld_ioc_vlan_attr_t *divp = karg;
544 dls_dl_handle_t dlh;
545 uint16_t vid;
546 dls_vlan_t *dvp;
547 int err;
548
549 /*
550 * Hold this link to prevent it from being deleted.
551 */
552 if ((err = dls_devnet_hold_tmp(divp->div_vlanid, &dlh)) != 0)
553 return (err);
554
555 if ((vid = dls_devnet_vid(dlh)) == VLAN_ID_NONE) {
556 dls_devnet_rele_tmp(dlh);
557 return (EINVAL);
558 }
559
560 err = dls_vlan_hold(dls_devnet_mac(dlh), vid, &dvp, B_FALSE, B_FALSE);
561 if (err != 0) {
562 dls_devnet_rele_tmp(dlh);
563 return (err);
564 }
565
566 divp->div_linkid = dls_devnet_linkid(dlh);
567 divp->div_implicit = !dls_devnet_is_explicit(dlh);
568 divp->div_vid = vid;
569 divp->div_force = dvp->dv_force;
570
571 dls_vlan_rele(dvp);
572 dls_devnet_rele_tmp(dlh);
573 return (0);
653 return (drv_ioc_prop_common(karg, arg, B_FALSE, mode));
574}
575
576/*
577 * DLDIOC_RENAME.
578 *
579 * This function handles two cases of link renaming. See more in comments above
580 * dls_datalink_rename().
581 */
582/* ARGSUSED */
583static int
654}
655
656/*
657 * DLDIOC_RENAME.
658 *
659 * This function handles two cases of link renaming. See more in comments above
660 * dls_datalink_rename().
661 */
662/* ARGSUSED */
663static int
584drv_ioc_rename(void *karg, intptr_t arg, int mode, cred_t *cred)
664drv_ioc_rename(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
585{
586 dld_ioc_rename_t *dir = karg;
587 mod_hash_key_t key;
588 mod_hash_val_t val;
589 int err;
590
591 if ((err = dls_devnet_rename(dir->dir_linkid1, dir->dir_linkid2,
592 dir->dir_link)) != 0)

--- 121 unchanged lines hidden (view full) ---

714 return (0);
715}
716
717/*
718 * DLDIOC_DOORSERVER
719 */
720/* ARGSUSED */
721static int
665{
666 dld_ioc_rename_t *dir = karg;
667 mod_hash_key_t key;
668 mod_hash_val_t val;
669 int err;
670
671 if ((err = dls_devnet_rename(dir->dir_linkid1, dir->dir_linkid2,
672 dir->dir_link)) != 0)

--- 121 unchanged lines hidden (view full) ---

794 return (0);
795}
796
797/*
798 * DLDIOC_DOORSERVER
799 */
800/* ARGSUSED */
801static int
722drv_ioc_doorserver(void *karg, intptr_t arg, int mode, cred_t *cred)
802drv_ioc_doorserver(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
723{
724 dld_ioc_door_t *did = karg;
725
726 return (dls_mgmt_door_set(did->did_start_door));
727}
728
729/*
803{
804 dld_ioc_door_t *did = karg;
805
806 return (dls_mgmt_door_set(did->did_start_door));
807}
808
809/*
810 * DLDIOC_USAGELOG
811 */
812/* ARGSUSED */
813static int
814drv_ioc_usagelog(void *karg, intptr_t arg, int mode, cred_t *cred,
815 int *rvalp)
816{
817 dld_ioc_usagelog_t *log_info = (dld_ioc_usagelog_t *)karg;
818
819 if (log_info->ul_type < MAC_LOGTYPE_LINK ||
820 log_info->ul_type > MAC_LOGTYPE_FLOW)
821 return (EINVAL);
822
823 if (log_info->ul_onoff)
824 mac_start_logusage(log_info->ul_type, log_info->ul_interval);
825 else
826 mac_stop_logusage(log_info->ul_type);
827 return (0);
828}
829
830/*
831 * Process a DLDIOC_ADDFLOW request.
832 */
833/* ARGSUSED */
834static int
835drv_ioc_addflow(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
836{
837 dld_ioc_addflow_t *afp = karg;
838
839 return (dld_add_flow(afp->af_linkid, afp->af_name,
840 &afp->af_flow_desc, &afp->af_resource_props));
841}
842
843/*
844 * Process a DLDIOC_REMOVEFLOW request.
845 */
846/* ARGSUSED */
847static int
848drv_ioc_removeflow(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
849{
850 dld_ioc_removeflow_t *rfp = karg;
851
852 return (dld_remove_flow(rfp->rf_name));
853}
854
855/*
856 * Process a DLDIOC_MODIFYFLOW request.
857 */
858/* ARGSUSED */
859static int
860drv_ioc_modifyflow(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
861{
862 dld_ioc_modifyflow_t *mfp = karg;
863
864 return (dld_modify_flow(mfp->mf_name, &mfp->mf_resource_props));
865}
866
867/*
868 * Process a DLDIOC_WALKFLOW request.
869 */
870/* ARGSUSED */
871static int
872drv_ioc_walkflow(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
873{
874 dld_ioc_walkflow_t *wfp = karg;
875
876 return (dld_walk_flow(wfp, arg));
877}
878
879/*
730 * Check for GLDv3 autopush information. There are three cases:
731 *
732 * 1. If devp points to a GLDv3 datalink and it has autopush configuration,
733 * fill dlap in with that information and return 0.
734 *
735 * 2. If devp points to a GLDv3 datalink but it doesn't have autopush
736 * configuration, then replace devp with the physical device (if one
737 * exists) and return 1. This allows stropen() to find the old-school

--- 66 unchanged lines hidden (view full) ---

804{
805 mod_hash_destroy_hash(drv_secobj_hash);
806 kmem_cache_destroy(drv_secobj_cachep);
807 rw_destroy(&drv_secobj_lock);
808}
809
810/* ARGSUSED */
811static int
880 * Check for GLDv3 autopush information. There are three cases:
881 *
882 * 1. If devp points to a GLDv3 datalink and it has autopush configuration,
883 * fill dlap in with that information and return 0.
884 *
885 * 2. If devp points to a GLDv3 datalink but it doesn't have autopush
886 * configuration, then replace devp with the physical device (if one
887 * exists) and return 1. This allows stropen() to find the old-school

--- 66 unchanged lines hidden (view full) ---

954{
955 mod_hash_destroy_hash(drv_secobj_hash);
956 kmem_cache_destroy(drv_secobj_cachep);
957 rw_destroy(&drv_secobj_lock);
958}
959
960/* ARGSUSED */
961static int
812drv_ioc_secobj_set(void *karg, intptr_t arg, int mode, cred_t *cred)
962drv_ioc_secobj_set(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
813{
814 dld_ioc_secobj_set_t *ssp = karg;
815 dld_secobj_t *sobjp, *objp;
816 int err;
817
818 sobjp = &ssp->ss_obj;
819
820 if (sobjp->so_class != DLD_SECOBJ_CLASS_WEP &&

--- 59 unchanged lines hidden (view full) ---

880 statep->ss_objp++;
881 statep->ss_free -= sizeof (dld_secobj_t);
882 statep->ss_count++;
883 return (MH_WALK_CONTINUE);
884}
885
886/* ARGSUSED */
887static int
963{
964 dld_ioc_secobj_set_t *ssp = karg;
965 dld_secobj_t *sobjp, *objp;
966 int err;
967
968 sobjp = &ssp->ss_obj;
969
970 if (sobjp->so_class != DLD_SECOBJ_CLASS_WEP &&

--- 59 unchanged lines hidden (view full) ---

1030 statep->ss_objp++;
1031 statep->ss_free -= sizeof (dld_secobj_t);
1032 statep->ss_count++;
1033 return (MH_WALK_CONTINUE);
1034}
1035
1036/* ARGSUSED */
1037static int
888drv_ioc_secobj_get(void *karg, intptr_t arg, int mode, cred_t *cred)
1038drv_ioc_secobj_get(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp)
889{
890 dld_ioc_secobj_get_t *sgp = karg;
891 dld_secobj_t *sobjp, *objp;
892 int err;
893
894 sobjp = &sgp->sg_obj;
1039{
1040 dld_ioc_secobj_get_t *sgp = karg;
1041 dld_secobj_t *sobjp, *objp;
1042 int err;
1043
1044 sobjp = &sgp->sg_obj;
895
896 if (sobjp->so_name[DLD_SECOBJ_NAME_MAX - 1] != '\0')
897 return (EINVAL);
898
899 rw_enter(&drv_secobj_lock, RW_READER);
900 if (sobjp->so_name[0] != '\0') {
901 err = mod_hash_find(drv_secobj_hash,
902 (mod_hash_key_t)sobjp->so_name, (mod_hash_val_t *)&objp);
903 if (err != 0) {

--- 23 unchanged lines hidden (view full) ---

927 sgp->sg_count = state.ss_count;
928 }
929 rw_exit(&drv_secobj_lock);
930 return (0);
931}
932
933/* ARGSUSED */
934static int
1045 if (sobjp->so_name[DLD_SECOBJ_NAME_MAX - 1] != '\0')
1046 return (EINVAL);
1047
1048 rw_enter(&drv_secobj_lock, RW_READER);
1049 if (sobjp->so_name[0] != '\0') {
1050 err = mod_hash_find(drv_secobj_hash,
1051 (mod_hash_key_t)sobjp->so_name, (mod_hash_val_t *)&objp);
1052 if (err != 0) {

--- 23 unchanged lines hidden (view full) ---

1076 sgp->sg_count = state.ss_count;
1077 }
1078 rw_exit(&drv_secobj_lock);
1079 return (0);
1080}
1081
1082/* ARGSUSED */
1083static int
935drv_ioc_secobj_unset(void *karg, intptr_t arg, int mode, cred_t *cred)
1084drv_ioc_secobj_unset(void *karg, intptr_t arg, int mode, cred_t *cred,
1085 int *rvalp)
936{
937 dld_ioc_secobj_unset_t *sup = karg;
938 dld_secobj_t *objp;
939 mod_hash_val_t val;
940 int err;
941
942 if (sup->su_name[DLD_SECOBJ_NAME_MAX - 1] != '\0')
943 return (EINVAL);

--- 10 unchanged lines hidden (view full) ---

954 (mod_hash_val_t *)&val) == 0);
955 ASSERT(objp == (dld_secobj_t *)val);
956
957 kmem_cache_free(drv_secobj_cachep, objp);
958 rw_exit(&drv_secobj_lock);
959 return (0);
960}
961
1086{
1087 dld_ioc_secobj_unset_t *sup = karg;
1088 dld_secobj_t *objp;
1089 mod_hash_val_t val;
1090 int err;
1091
1092 if (sup->su_name[DLD_SECOBJ_NAME_MAX - 1] != '\0')
1093 return (EINVAL);

--- 10 unchanged lines hidden (view full) ---

1104 (mod_hash_val_t *)&val) == 0);
1105 ASSERT(objp == (dld_secobj_t *)val);
1106
1107 kmem_cache_free(drv_secobj_cachep, objp);
1108 rw_exit(&drv_secobj_lock);
1109 return (0);
1110}
1111
1112static int
1113drv_check_policy(dld_ioc_info_t *info, cred_t *cred)
1114{
1115 int i, err = 0;
1116
1117 for (i = 0; info->di_priv[i] != NULL && i < DLD_MAX_PRIV; i++) {
1118 if ((err = secpolicy_dld_ioctl(cred, info->di_priv[i],
1119 "dld ioctl")) != 0) {
1120 break;
1121 }
1122 }
1123 if (err == 0)
1124 return (0);
1125
1126 return (secpolicy_net_config(cred, B_FALSE));
1127}
1128
962static dld_ioc_info_t drv_ioc_list[] = {
963 {DLDIOC_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_attr_t),
1129static dld_ioc_info_t drv_ioc_list[] = {
1130 {DLDIOC_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_attr_t),
964 drv_ioc_attr},
1131 drv_ioc_attr, {NULL}},
965 {DLDIOC_PHYS_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_phys_attr_t),
1132 {DLDIOC_PHYS_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_phys_attr_t),
966 drv_ioc_phys_attr},
967 {DLDIOC_SECOBJ_SET, DLDCOPYIN | DLDDLCONFIG,
968 sizeof (dld_ioc_secobj_set_t), drv_ioc_secobj_set},
969 {DLDIOC_SECOBJ_GET, DLDCOPYINOUT | DLDDLCONFIG,
970 sizeof (dld_ioc_secobj_get_t), drv_ioc_secobj_get},
971 {DLDIOC_SECOBJ_UNSET, DLDCOPYIN | DLDDLCONFIG,
972 sizeof (dld_ioc_secobj_unset_t), drv_ioc_secobj_unset},
973 {DLDIOC_CREATE_VLAN, DLDCOPYIN | DLDDLCONFIG,
974 sizeof (dld_ioc_create_vlan_t), drv_ioc_create_vlan},
975 {DLDIOC_DELETE_VLAN, DLDCOPYIN | DLDDLCONFIG,
976 sizeof (dld_ioc_delete_vlan_t),
977 drv_ioc_delete_vlan},
978 {DLDIOC_VLAN_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_vlan_attr_t),
979 drv_ioc_vlan_attr},
980 {DLDIOC_DOORSERVER, DLDCOPYIN | DLDDLCONFIG, sizeof (dld_ioc_door_t),
981 drv_ioc_doorserver},
982 {DLDIOC_RENAME, DLDCOPYIN | DLDDLCONFIG, sizeof (dld_ioc_rename_t),
983 drv_ioc_rename},
1133 drv_ioc_phys_attr, {NULL}},
1134 {DLDIOC_SECOBJ_SET, DLDCOPYIN, sizeof (dld_ioc_secobj_set_t),
1135 drv_ioc_secobj_set, {PRIV_SYS_DL_CONFIG}},
1136 {DLDIOC_SECOBJ_GET, DLDCOPYINOUT, sizeof (dld_ioc_secobj_get_t),
1137 drv_ioc_secobj_get, {PRIV_SYS_DL_CONFIG}},
1138 {DLDIOC_SECOBJ_UNSET, DLDCOPYIN, sizeof (dld_ioc_secobj_unset_t),
1139 drv_ioc_secobj_unset, {PRIV_SYS_DL_CONFIG}},
1140 {DLDIOC_DOORSERVER, DLDCOPYIN, sizeof (dld_ioc_door_t),
1141 drv_ioc_doorserver, {PRIV_SYS_DL_CONFIG}},
1142 {DLDIOC_RENAME, DLDCOPYIN, sizeof (dld_ioc_rename_t),
1143 drv_ioc_rename, {PRIV_SYS_DL_CONFIG}},
1144 {DLDIOC_MACADDRGET, DLDCOPYINOUT, sizeof (dld_ioc_macaddrget_t),
1145 drv_ioc_macaddrget, {PRIV_SYS_DL_CONFIG}},
1146 {DLDIOC_ADDFLOW, DLDCOPYIN, sizeof (dld_ioc_addflow_t),
1147 drv_ioc_addflow, {PRIV_SYS_DL_CONFIG}},
1148 {DLDIOC_REMOVEFLOW, DLDCOPYIN, sizeof (dld_ioc_removeflow_t),
1149 drv_ioc_removeflow, {PRIV_SYS_DL_CONFIG}},
1150 {DLDIOC_MODIFYFLOW, DLDCOPYIN, sizeof (dld_ioc_modifyflow_t),
1151 drv_ioc_modifyflow, {PRIV_SYS_DL_CONFIG}},
1152 {DLDIOC_WALKFLOW, DLDCOPYINOUT, sizeof (dld_ioc_walkflow_t),
1153 drv_ioc_walkflow, {NULL}},
1154 {DLDIOC_USAGELOG, DLDCOPYIN, sizeof (dld_ioc_usagelog_t),
1155 drv_ioc_usagelog, {PRIV_SYS_DL_CONFIG}},
1156 {DLDIOC_SETMACPROP, DLDCOPYIN, sizeof (dld_ioc_macprop_t),
1157 drv_ioc_setprop, {PRIV_SYS_DL_CONFIG}},
984 {DLDIOC_GETMACPROP, DLDCOPYIN, sizeof (dld_ioc_macprop_t),
1158 {DLDIOC_GETMACPROP, DLDCOPYIN, sizeof (dld_ioc_macprop_t),
985 drv_ioc_getprop},
986 {DLDIOC_SETMACPROP, DLDCOPYIN | DLDDLCONFIG, sizeof (dld_ioc_macprop_t),
987 drv_ioc_setprop}
1159 drv_ioc_getprop, {NULL}},
1160 {DLDIOC_GETHWGRP, DLDCOPYINOUT, sizeof (dld_ioc_hwgrpget_t),
1161 drv_ioc_hwgrpget, {PRIV_SYS_DL_CONFIG}},
988};
989
990typedef struct dld_ioc_modentry {
991 uint16_t dim_modid; /* Top 16 bits of ioctl command */
992 char *dim_modname; /* Module to be loaded */
993 dld_ioc_info_t *dim_list; /* array of ioctl structures */
994 uint_t dim_count; /* number of elements in dim_list */
995} dld_ioc_modentry_t;

--- 89 unchanged lines hidden (view full) ---

1085 break;
1086 }
1087 if (i == dim->dim_count) {
1088 err = ENOTSUP;
1089 goto done;
1090 }
1091
1092 info = &dim->dim_list[i];
1162};
1163
1164typedef struct dld_ioc_modentry {
1165 uint16_t dim_modid; /* Top 16 bits of ioctl command */
1166 char *dim_modname; /* Module to be loaded */
1167 dld_ioc_info_t *dim_list; /* array of ioctl structures */
1168 uint_t dim_count; /* number of elements in dim_list */
1169} dld_ioc_modentry_t;

--- 89 unchanged lines hidden (view full) ---

1259 break;
1260 }
1261 if (i == dim->dim_count) {
1262 err = ENOTSUP;
1263 goto done;
1264 }
1265
1266 info = &dim->dim_list[i];
1093
1094 if ((info->di_flags & DLDDLCONFIG) && secpolicy_dl_config(cred) != 0) {
1095 err = EPERM;
1267 if ((err = drv_check_policy(info, cred)) != 0)
1096 goto done;
1268 goto done;
1097 }
1098
1099 sz = info->di_argsize;
1100 if ((buf = kmem_zalloc(sz, KM_NOSLEEP)) == NULL) {
1101 err = ENOMEM;
1102 goto done;
1103 }
1104
1105 if ((info->di_flags & DLDCOPYIN) &&
1106 ddi_copyin((void *)arg, buf, sz, mode) != 0) {
1107 err = EFAULT;
1108 goto done;
1109 }
1110
1269
1270 sz = info->di_argsize;
1271 if ((buf = kmem_zalloc(sz, KM_NOSLEEP)) == NULL) {
1272 err = ENOMEM;
1273 goto done;
1274 }
1275
1276 if ((info->di_flags & DLDCOPYIN) &&
1277 ddi_copyin((void *)arg, buf, sz, mode) != 0) {
1278 err = EFAULT;
1279 goto done;
1280 }
1281
1111 err = info->di_func(buf, arg, mode, cred);
1282 err = info->di_func(buf, arg, mode, cred, rvalp);
1112
1113 if ((info->di_flags & DLDCOPYOUT) &&
1114 ddi_copyout(buf, (void *)arg, sz, mode) != 0 && err == 0)
1115 err = EFAULT;
1116
1117done:
1118 if (buf != NULL)
1119 kmem_free(buf, sz);
1120 if (dip != NULL)
1121 ddi_release_devi(dip);
1122 return (err);
1123}
1283
1284 if ((info->di_flags & DLDCOPYOUT) &&
1285 ddi_copyout(buf, (void *)arg, sz, mode) != 0 && err == 0)
1286 err = EFAULT;
1287
1288done:
1289 if (buf != NULL)
1290 kmem_free(buf, sz);
1291 if (dip != NULL)
1292 ddi_release_devi(dip);
1293 return (err);
1294}