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;
 
 |