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
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2015, Joyent Inc.
24 * Copyright (c) 2017, Joyent, Inc.
25 */
26
27 /*
28 * Data-Link Driver
29 */
30
31 #include <sys/conf.h>
32 #include <sys/mkdev.h>
33 #include <sys/modctl.h>
34 #include <sys/stat.h>
35 #include <sys/dld_impl.h>
36 #include <sys/dld_ioc.h>
37 #include <sys/dls_impl.h>
38 #include <sys/softmac.h>
39 #include <sys/mac.h>
40 #include <sys/mac_ether.h>
41 #include <sys/mac_client.h>
42 #include <sys/mac_client_impl.h>
43 #include <sys/mac_client_priv.h>
44 #include <inet/common.h>
607 mai.dmi_flags |= DLDIOCMACADDR_USED;
608
609 if (copyout(&mai, maip, sizeof (mai)) != 0) {
610 err = EFAULT;
611 goto done;
612 }
613
614 maip++;
615 bytes_left -= sizeof (dld_macaddrinfo_t);
616 }
617
618 done:
619 if (mh != NULL)
620 dld_mac_close(mh);
621 if (err == 0)
622 magp->dig_count = mac_addr_factory_num(mh) + 1;
623 return (err);
624 }
625
626 /*
627 * DLDIOC_SET/GETMACPROP
628 */
629 static int
630 drv_ioc_prop_common(dld_ioc_macprop_t *prop, intptr_t arg, boolean_t set,
631 cred_t *cred, int mode)
632 {
633 int err = EINVAL;
634 dls_dl_handle_t dlh = NULL;
635 dls_link_t *dlp = NULL;
636 mac_perim_handle_t mph = NULL;
637 dld_ioc_macprop_t *kprop;
638 datalink_id_t linkid;
639 datalink_class_t class;
640 zoneid_t zoneid = crgetzoneid(cred);
641 uint_t dsize;
642
643 /*
644 * We only use pr_valsize from prop, as the caller only did a
645 * copyin() for sizeof (dld_ioc_prop_t), which doesn't cover
646 * the property data. We copyin the full dld_ioc_prop_t
662 err = EFAULT;
663 goto done;
664 }
665
666 linkid = kprop->pr_linkid;
667
668 if (set) {
669 if ((err = dls_mgmt_get_linkinfo(linkid, NULL, &class, NULL,
670 NULL)) != 0 || (err = drv_ioc_checkprivs(class, cred)) != 0)
671 goto done;
672 }
673
674 if ((err = dls_devnet_hold_tmp(linkid, &dlh)) != 0)
675 goto done;
676 if ((err = mac_perim_enter_by_macname(dls_devnet_mac(dlh), &mph)) != 0)
677 goto done;
678 if ((err = dls_link_hold(dls_devnet_mac(dlh), &dlp)) != 0)
679 goto done;
680
681 /*
682 * Don't allow a process to get or set properties of a link if that
683 * link doesn't belong to that zone.
684 */
685 if (zoneid != dls_devnet_getownerzid(dlh)) {
686 err = ENOENT;
687 goto done;
688 }
689
690 if (!mac_prop_check_size(kprop->pr_num, kprop->pr_valsize,
691 kprop->pr_flags & DLD_PROP_POSSIBLE)) {
692 err = ENOBUFS;
693 goto done;
694 }
695
696 switch (kprop->pr_num) {
697 case MAC_PROP_ZONE:
698 if (set) {
699 dld_ioc_zid_t *dzp = (dld_ioc_zid_t *)kprop->pr_val;
700
701 if (zoneid != GLOBAL_ZONEID) {
702 err = EACCES;
703 goto done;
704 }
705 err = dls_devnet_setzid(dlh, dzp->diz_zid);
|
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
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2015, Joyent Inc.
24 * Copyright (c) 2017, Joyent, Inc.
25 * Copyright 2025 MNX Cloud, Inc.
26 */
27
28 /*
29 * Data-Link Driver
30 */
31
32 #include <sys/conf.h>
33 #include <sys/mkdev.h>
34 #include <sys/modctl.h>
35 #include <sys/stat.h>
36 #include <sys/dld_impl.h>
37 #include <sys/dld_ioc.h>
38 #include <sys/dls_impl.h>
39 #include <sys/softmac.h>
40 #include <sys/mac.h>
41 #include <sys/mac_ether.h>
42 #include <sys/mac_client.h>
43 #include <sys/mac_client_impl.h>
44 #include <sys/mac_client_priv.h>
45 #include <inet/common.h>
608 mai.dmi_flags |= DLDIOCMACADDR_USED;
609
610 if (copyout(&mai, maip, sizeof (mai)) != 0) {
611 err = EFAULT;
612 goto done;
613 }
614
615 maip++;
616 bytes_left -= sizeof (dld_macaddrinfo_t);
617 }
618
619 done:
620 if (mh != NULL)
621 dld_mac_close(mh);
622 if (err == 0)
623 magp->dig_count = mac_addr_factory_num(mh) + 1;
624 return (err);
625 }
626
627 /*
628 * Sometimes DLDIOC_GETMACPROP (and in the future, possibly DLDIOC_SETMACPROP)
629 * may be allowed to be accessed by the zone that is assigned the datalink
630 * device, as opposed to the zone that created the device.
631 */
632 static boolean_t
633 dld_macprop_assigned_zone_exception(zoneid_t zoneid, dls_dl_handle_t dlh,
634 dld_ioc_macprop_t *kprop, boolean_t set)
635 {
636 /*
637 * No exceptions for setting! No exceptions unless the zoneid is
638 * the assigned zone.
639 */
640 if (set || zoneid != dls_devnet_getzid(dlh))
641 return (B_FALSE);
642
643 /*
644 * The current list of read-only exceptions are enumerated below.
645 */
646 switch (kprop->pr_num) {
647 case MAC_PROP_MTU:
648 case MAC_PROP_STATUS:
649 return (B_TRUE);
650 default:
651 return (B_FALSE);
652 }
653 }
654
655 /*
656 * DLDIOC_SET/GETMACPROP
657 */
658 static int
659 drv_ioc_prop_common(dld_ioc_macprop_t *prop, intptr_t arg, boolean_t set,
660 cred_t *cred, int mode)
661 {
662 int err = EINVAL;
663 dls_dl_handle_t dlh = NULL;
664 dls_link_t *dlp = NULL;
665 mac_perim_handle_t mph = NULL;
666 dld_ioc_macprop_t *kprop;
667 datalink_id_t linkid;
668 datalink_class_t class;
669 zoneid_t zoneid = crgetzoneid(cred);
670 uint_t dsize;
671
672 /*
673 * We only use pr_valsize from prop, as the caller only did a
674 * copyin() for sizeof (dld_ioc_prop_t), which doesn't cover
675 * the property data. We copyin the full dld_ioc_prop_t
691 err = EFAULT;
692 goto done;
693 }
694
695 linkid = kprop->pr_linkid;
696
697 if (set) {
698 if ((err = dls_mgmt_get_linkinfo(linkid, NULL, &class, NULL,
699 NULL)) != 0 || (err = drv_ioc_checkprivs(class, cred)) != 0)
700 goto done;
701 }
702
703 if ((err = dls_devnet_hold_tmp(linkid, &dlh)) != 0)
704 goto done;
705 if ((err = mac_perim_enter_by_macname(dls_devnet_mac(dlh), &mph)) != 0)
706 goto done;
707 if ((err = dls_link_hold(dls_devnet_mac(dlh), &dlp)) != 0)
708 goto done;
709
710 /*
711 * In general, don't allow a process to get or set properties of a
712 * link if that link doesn't belong to that zone.
713 *
714 * There are exceptions however, if the dlh's *assigned* zone (as
715 * determined by dls_devnet_getzid()) is the one calling here. See
716 * the local function dld_macprop_assigned_zone_exception() above.
717 */
718 if (zoneid != dls_devnet_getownerzid(dlh) &&
719 !dld_macprop_assigned_zone_exception(zoneid, dlh, kprop, set)) {
720 err = ENOENT;
721 goto done;
722 }
723
724 if (!mac_prop_check_size(kprop->pr_num, kprop->pr_valsize,
725 kprop->pr_flags & DLD_PROP_POSSIBLE)) {
726 err = ENOBUFS;
727 goto done;
728 }
729
730 switch (kprop->pr_num) {
731 case MAC_PROP_ZONE:
732 if (set) {
733 dld_ioc_zid_t *dzp = (dld_ioc_zid_t *)kprop->pr_val;
734
735 if (zoneid != GLOBAL_ZONEID) {
736 err = EACCES;
737 goto done;
738 }
739 err = dls_devnet_setzid(dlh, dzp->diz_zid);
|