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
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) 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2012, Nexenta Systems, Inc. All rights reserved.
24 */
25
26 /*
27 * Data-Link Driver
28 */
29 #include <sys/sysmacros.h>
30 #include <sys/strsubr.h>
31 #include <sys/strsun.h>
32 #include <sys/vlan.h>
33 #include <sys/dld_impl.h>
34 #include <sys/mac_client.h>
35 #include <sys/mac_client_impl.h>
36 #include <sys/mac_client_priv.h>
37
38 typedef void proto_reqfunc_t(dld_str_t *, mblk_t *);
39
40 static proto_reqfunc_t proto_info_req, proto_attach_req, proto_detach_req,
41 proto_bind_req, proto_unbind_req, proto_promiscon_req, proto_promiscoff_req,
42 proto_enabmulti_req, proto_disabmulti_req, proto_physaddr_req,
43 proto_setphysaddr_req, proto_udqos_req, proto_req, proto_capability_req,
665 mac_perim_handle_t mph;
666
667 if (MBLKL(mp) < sizeof (dl_promiscoff_req_t)) {
668 dl_err = DL_BADPRIM;
669 goto failed;
670 }
671
672 if (dsp->ds_dlstate == DL_UNATTACHED ||
673 DL_ACK_PENDING(dsp->ds_dlstate)) {
674 dl_err = DL_OUTSTATE;
675 goto failed;
676 }
677
678 mac_perim_enter_by_mh(dsp->ds_mh, &mph);
679
680 new_flags = dsp->ds_promisc;
681 switch (dlp->dl_level) {
682 case DL_PROMISC_SAP:
683 if (!(dsp->ds_promisc & DLS_PROMISC_SAP)) {
684 dl_err = DL_NOTENAB;
685 goto failed;
686 }
687 new_flags &= ~DLS_PROMISC_SAP;
688 break;
689
690 case DL_PROMISC_MULTI:
691 if (!(dsp->ds_promisc & DLS_PROMISC_MULTI)) {
692 dl_err = DL_NOTENAB;
693 goto failed;
694 }
695 new_flags &= ~DLS_PROMISC_MULTI;
696 break;
697
698 case DL_PROMISC_PHYS:
699 if (!(dsp->ds_promisc & DLS_PROMISC_PHYS)) {
700 dl_err = DL_NOTENAB;
701 goto failed;
702 }
703 new_flags &= ~DLS_PROMISC_PHYS;
704 break;
705
706 case DL_PROMISC_RX_ONLY:
707 if (!(dsp->ds_promisc & DLS_PROMISC_RX_ONLY)) {
708 dl_err = DL_NOTENAB;
709 goto failed;
710 }
711 new_flags &= ~DLS_PROMISC_RX_ONLY;
712 break;
713
714 case DL_PROMISC_FIXUPS:
715 if (!(dsp->ds_promisc & DLS_PROMISC_FIXUPS)) {
716 dl_err = DL_NOTENAB;
717 goto failed;
718 }
719 new_flags &= ~DLS_PROMISC_FIXUPS;
720 break;
721
722 default:
723 dl_err = DL_NOTSUPPORTED;
724 mac_perim_exit(mph);
725 goto failed;
726 }
727
728 /*
729 * Adjust channel promiscuity.
730 */
731 err = dls_promisc(dsp, new_flags);
732
733 if (err != 0) {
734 mac_perim_exit(mph);
735 dl_err = DL_SYSERR;
736 goto failed;
737 }
738
739 ASSERT(dsp->ds_promisc == new_flags);
740 if (dsp->ds_promisc == 0)
741 dls_active_clear(dsp, B_FALSE);
742
743 mac_perim_exit(mph);
744
745 dlokack(q, mp, DL_PROMISCOFF_REQ);
746 return;
747 failed:
748 dlerrorack(q, mp, DL_PROMISCOFF_REQ, dl_err, (t_uscalar_t)err);
749 }
750
751 /*
752 * DL_ENABMULTI_REQ
753 */
754 static void
755 proto_enabmulti_req(dld_str_t *dsp, mblk_t *mp)
756 {
757 dl_enabmulti_req_t *dlp = (dl_enabmulti_req_t *)mp->b_rptr;
758 int err = 0;
759 t_uscalar_t dl_err;
760 queue_t *q = dsp->ds_wq;
761 mac_perim_handle_t mph;
762
763 if (dsp->ds_dlstate == DL_UNATTACHED ||
764 DL_ACK_PENDING(dsp->ds_dlstate)) {
765 dl_err = DL_OUTSTATE;
766 goto failed;
|
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
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) 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2012, Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2017 Joyent, Inc.
25 */
26
27 /*
28 * Data-Link Driver
29 */
30 #include <sys/sysmacros.h>
31 #include <sys/strsubr.h>
32 #include <sys/strsun.h>
33 #include <sys/vlan.h>
34 #include <sys/dld_impl.h>
35 #include <sys/mac_client.h>
36 #include <sys/mac_client_impl.h>
37 #include <sys/mac_client_priv.h>
38
39 typedef void proto_reqfunc_t(dld_str_t *, mblk_t *);
40
41 static proto_reqfunc_t proto_info_req, proto_attach_req, proto_detach_req,
42 proto_bind_req, proto_unbind_req, proto_promiscon_req, proto_promiscoff_req,
43 proto_enabmulti_req, proto_disabmulti_req, proto_physaddr_req,
44 proto_setphysaddr_req, proto_udqos_req, proto_req, proto_capability_req,
666 mac_perim_handle_t mph;
667
668 if (MBLKL(mp) < sizeof (dl_promiscoff_req_t)) {
669 dl_err = DL_BADPRIM;
670 goto failed;
671 }
672
673 if (dsp->ds_dlstate == DL_UNATTACHED ||
674 DL_ACK_PENDING(dsp->ds_dlstate)) {
675 dl_err = DL_OUTSTATE;
676 goto failed;
677 }
678
679 mac_perim_enter_by_mh(dsp->ds_mh, &mph);
680
681 new_flags = dsp->ds_promisc;
682 switch (dlp->dl_level) {
683 case DL_PROMISC_SAP:
684 if (!(dsp->ds_promisc & DLS_PROMISC_SAP)) {
685 dl_err = DL_NOTENAB;
686 goto failed2;
687 }
688 new_flags &= ~DLS_PROMISC_SAP;
689 break;
690
691 case DL_PROMISC_MULTI:
692 if (!(dsp->ds_promisc & DLS_PROMISC_MULTI)) {
693 dl_err = DL_NOTENAB;
694 goto failed2;
695 }
696 new_flags &= ~DLS_PROMISC_MULTI;
697 break;
698
699 case DL_PROMISC_PHYS:
700 if (!(dsp->ds_promisc & DLS_PROMISC_PHYS)) {
701 dl_err = DL_NOTENAB;
702 goto failed2;
703 }
704 new_flags &= ~DLS_PROMISC_PHYS;
705 break;
706
707 case DL_PROMISC_RX_ONLY:
708 if (!(dsp->ds_promisc & DLS_PROMISC_RX_ONLY)) {
709 dl_err = DL_NOTENAB;
710 goto failed2;
711 }
712 new_flags &= ~DLS_PROMISC_RX_ONLY;
713 break;
714
715 case DL_PROMISC_FIXUPS:
716 if (!(dsp->ds_promisc & DLS_PROMISC_FIXUPS)) {
717 dl_err = DL_NOTENAB;
718 goto failed2;
719 }
720 new_flags &= ~DLS_PROMISC_FIXUPS;
721 break;
722
723 default:
724 dl_err = DL_NOTSUPPORTED;
725 goto failed2;
726 }
727
728 /*
729 * Adjust channel promiscuity.
730 */
731 err = dls_promisc(dsp, new_flags);
732
733 if (err != 0) {
734 dl_err = DL_SYSERR;
735 goto failed2;
736 }
737
738 ASSERT(dsp->ds_promisc == new_flags);
739 if (dsp->ds_promisc == 0)
740 dls_active_clear(dsp, B_FALSE);
741
742 mac_perim_exit(mph);
743
744 dlokack(q, mp, DL_PROMISCOFF_REQ);
745 return;
746 failed2:
747 mac_perim_exit(mph);
748 failed:
749 dlerrorack(q, mp, DL_PROMISCOFF_REQ, dl_err, (t_uscalar_t)err);
750 }
751
752 /*
753 * DL_ENABMULTI_REQ
754 */
755 static void
756 proto_enabmulti_req(dld_str_t *dsp, mblk_t *mp)
757 {
758 dl_enabmulti_req_t *dlp = (dl_enabmulti_req_t *)mp->b_rptr;
759 int err = 0;
760 t_uscalar_t dl_err;
761 queue_t *q = dsp->ds_wq;
762 mac_perim_handle_t mph;
763
764 if (dsp->ds_dlstate == DL_UNATTACHED ||
765 DL_ACK_PENDING(dsp->ds_dlstate)) {
766 dl_err = DL_OUTSTATE;
767 goto failed;
|