Print this page
1918 stack overflow from mac_promisc_dispatch()


   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
   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  */
  24 
  25 /*
  26  * Data-Link Driver
  27  */
  28 #include <sys/sysmacros.h>
  29 #include <sys/strsubr.h>
  30 #include <sys/strsun.h>
  31 #include <sys/vlan.h>
  32 #include <sys/dld_impl.h>
  33 #include <sys/mac_client.h>
  34 #include <sys/mac_client_impl.h>
  35 #include <sys/mac_client_priv.h>
  36 
  37 typedef void proto_reqfunc_t(dld_str_t *, mblk_t *);
  38 
  39 static proto_reqfunc_t proto_info_req, proto_attach_req, proto_detach_req,
  40     proto_bind_req, proto_unbind_req, proto_promiscon_req, proto_promiscoff_req,
  41     proto_enabmulti_req, proto_disabmulti_req, proto_physaddr_req,
  42     proto_setphysaddr_req, proto_udqos_req, proto_req, proto_capability_req,


 556         dsp->ds_mode = DLD_UNITDATA;
 557         dsp->ds_dlstate = DL_UNBOUND;
 558 
 559         dls_active_clear(dsp, B_FALSE);
 560         mac_perim_exit(mph);
 561         dlokack(dsp->ds_wq, mp, DL_UNBIND_REQ);
 562         return;
 563 failed:
 564         dlerrorack(q, mp, DL_UNBIND_REQ, dl_err, 0);
 565 }
 566 
 567 /*
 568  * DL_PROMISCON_REQ
 569  */
 570 static void
 571 proto_promiscon_req(dld_str_t *dsp, mblk_t *mp)
 572 {
 573         dl_promiscon_req_t *dlp = (dl_promiscon_req_t *)mp->b_rptr;
 574         int             err = 0;
 575         t_uscalar_t     dl_err;
 576         uint32_t        promisc_saved;
 577         queue_t         *q = dsp->ds_wq;
 578         mac_perim_handle_t      mph;
 579 
 580         if (MBLKL(mp) < sizeof (dl_promiscon_req_t)) {
 581                 dl_err = DL_BADPRIM;
 582                 goto failed;
 583         }
 584 
 585         if (dsp->ds_dlstate == DL_UNATTACHED ||
 586             DL_ACK_PENDING(dsp->ds_dlstate)) {
 587                 dl_err = DL_OUTSTATE;
 588                 goto failed;
 589         }
 590 
 591         promisc_saved = dsp->ds_promisc;


 592         switch (dlp->dl_level) {
 593         case DL_PROMISC_SAP:
 594                 dsp->ds_promisc |= DLS_PROMISC_SAP;
 595                 break;
 596 
 597         case DL_PROMISC_MULTI:
 598                 dsp->ds_promisc |= DLS_PROMISC_MULTI;
 599                 break;
 600 
 601         case DL_PROMISC_PHYS:
 602                 dsp->ds_promisc |= DLS_PROMISC_PHYS;
 603                 break;
 604 
 605         default:
 606                 dl_err = DL_NOTSUPPORTED;
 607                 goto failed;
 608         }
 609 
 610         mac_perim_enter_by_mh(dsp->ds_mh, &mph);
 611 
 612         if ((promisc_saved == 0) && (err = dls_active_set(dsp)) != 0) {
 613                 dsp->ds_promisc = promisc_saved;
 614                 dl_err = DL_SYSERR;
 615                 goto failed2;
 616         }
 617 
 618         /*
 619          * Adjust channel promiscuity.
 620          */
 621         err = dls_promisc(dsp, promisc_saved);
 622 
 623         if (err != 0) {
 624                 dl_err = DL_SYSERR;
 625                 dsp->ds_promisc = promisc_saved;
 626                 if (promisc_saved == 0)
 627                         dls_active_clear(dsp, B_FALSE);
 628                 goto failed2;
 629         }
 630 
 631         mac_perim_exit(mph);
 632 
 633         dlokack(q, mp, DL_PROMISCON_REQ);
 634         return;
 635 
 636 failed2:
 637         mac_perim_exit(mph);
 638 failed:
 639         dlerrorack(q, mp, DL_PROMISCON_REQ, dl_err, (t_uscalar_t)err);
 640 }
 641 
 642 /*
 643  * DL_PROMISCOFF_REQ
 644  */
 645 static void
 646 proto_promiscoff_req(dld_str_t *dsp, mblk_t *mp)
 647 {
 648         dl_promiscoff_req_t *dlp = (dl_promiscoff_req_t *)mp->b_rptr;
 649         int             err = 0;
 650         t_uscalar_t     dl_err;
 651         uint32_t        promisc_saved;
 652         queue_t         *q = dsp->ds_wq;
 653         mac_perim_handle_t      mph;
 654 
 655         if (MBLKL(mp) < sizeof (dl_promiscoff_req_t)) {
 656                 dl_err = DL_BADPRIM;
 657                 goto failed;
 658         }
 659 
 660         if (dsp->ds_dlstate == DL_UNATTACHED ||
 661             DL_ACK_PENDING(dsp->ds_dlstate)) {
 662                 dl_err = DL_OUTSTATE;
 663                 goto failed;
 664         }
 665 
 666         promisc_saved = dsp->ds_promisc;


 667         switch (dlp->dl_level) {
 668         case DL_PROMISC_SAP:
 669                 if (!(dsp->ds_promisc & DLS_PROMISC_SAP)) {
 670                         dl_err = DL_NOTENAB;
 671                         goto failed;
 672                 }
 673                 dsp->ds_promisc &= ~DLS_PROMISC_SAP;
 674                 break;
 675 
 676         case DL_PROMISC_MULTI:
 677                 if (!(dsp->ds_promisc & DLS_PROMISC_MULTI)) {
 678                         dl_err = DL_NOTENAB;
 679                         goto failed;
 680                 }
 681                 dsp->ds_promisc &= ~DLS_PROMISC_MULTI;
 682                 break;
 683 
 684         case DL_PROMISC_PHYS:
 685                 if (!(dsp->ds_promisc & DLS_PROMISC_PHYS)) {
 686                         dl_err = DL_NOTENAB;
 687                         goto failed;
 688                 }
 689                 dsp->ds_promisc &= ~DLS_PROMISC_PHYS;
 690                 break;
 691 
 692         default:
 693                 dl_err = DL_NOTSUPPORTED;
 694                 goto failed;
 695         }
 696 
 697         mac_perim_enter_by_mh(dsp->ds_mh, &mph);
 698         /*
 699          * Adjust channel promiscuity.
 700          */
 701         err = dls_promisc(dsp, promisc_saved);
 702 
 703         if (err != 0) {
 704                 mac_perim_exit(mph);
 705                 dl_err = DL_SYSERR;
 706                 goto failed;
 707         }
 708 

 709         if (dsp->ds_promisc == 0)
 710                 dls_active_clear(dsp, B_FALSE);
 711 
 712         mac_perim_exit(mph);
 713 
 714         dlokack(q, mp, DL_PROMISCOFF_REQ);
 715         return;
 716 failed:
 717         dlerrorack(q, mp, DL_PROMISCOFF_REQ, dl_err, (t_uscalar_t)err);
 718 }
 719 
 720 /*
 721  * DL_ENABMULTI_REQ
 722  */
 723 static void
 724 proto_enabmulti_req(dld_str_t *dsp, mblk_t *mp)
 725 {
 726         dl_enabmulti_req_t *dlp = (dl_enabmulti_req_t *)mp->b_rptr;
 727         int             err = 0;
 728         t_uscalar_t     dl_err;




   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
   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 2011, 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,


 557         dsp->ds_mode = DLD_UNITDATA;
 558         dsp->ds_dlstate = DL_UNBOUND;
 559 
 560         dls_active_clear(dsp, B_FALSE);
 561         mac_perim_exit(mph);
 562         dlokack(dsp->ds_wq, mp, DL_UNBIND_REQ);
 563         return;
 564 failed:
 565         dlerrorack(q, mp, DL_UNBIND_REQ, dl_err, 0);
 566 }
 567 
 568 /*
 569  * DL_PROMISCON_REQ
 570  */
 571 static void
 572 proto_promiscon_req(dld_str_t *dsp, mblk_t *mp)
 573 {
 574         dl_promiscon_req_t *dlp = (dl_promiscon_req_t *)mp->b_rptr;
 575         int             err = 0;
 576         t_uscalar_t     dl_err;
 577         uint32_t        new_flags, promisc_saved;
 578         queue_t         *q = dsp->ds_wq;
 579         mac_perim_handle_t      mph;
 580 
 581         if (MBLKL(mp) < sizeof (dl_promiscon_req_t)) {
 582                 dl_err = DL_BADPRIM;
 583                 goto failed;
 584         }
 585 
 586         if (dsp->ds_dlstate == DL_UNATTACHED ||
 587             DL_ACK_PENDING(dsp->ds_dlstate)) {
 588                 dl_err = DL_OUTSTATE;
 589                 goto failed;
 590         }
 591 
 592         mac_perim_enter_by_mh(dsp->ds_mh, &mph);
 593 
 594         new_flags = promisc_saved = dsp->ds_promisc;
 595         switch (dlp->dl_level) {
 596         case DL_PROMISC_SAP:
 597                 new_flags |= DLS_PROMISC_SAP;
 598                 break;
 599 
 600         case DL_PROMISC_MULTI:
 601                 new_flags |= DLS_PROMISC_MULTI;
 602                 break;
 603 
 604         case DL_PROMISC_PHYS:
 605                 new_flags |= DLS_PROMISC_PHYS;
 606                 break;
 607 
 608         default:
 609                 dl_err = DL_NOTSUPPORTED;
 610                 goto failed;
 611         }
 612 


 613         if ((promisc_saved == 0) && (err = dls_active_set(dsp)) != 0) {
 614                 ASSERT(dsp->ds_promisc == promisc_saved);
 615                 dl_err = DL_SYSERR;
 616                 goto failed2;
 617         }
 618 
 619         /*
 620          * Adjust channel promiscuity.
 621          */
 622         err = dls_promisc(dsp, new_flags);
 623 
 624         if (err != 0) {
 625                 dl_err = DL_SYSERR;
 626                 dsp->ds_promisc = promisc_saved;
 627                 if (promisc_saved == 0)
 628                         dls_active_clear(dsp, B_FALSE);
 629                 goto failed2;
 630         }
 631 
 632         mac_perim_exit(mph);
 633 
 634         dlokack(q, mp, DL_PROMISCON_REQ);
 635         return;
 636 
 637 failed2:
 638         mac_perim_exit(mph);
 639 failed:
 640         dlerrorack(q, mp, DL_PROMISCON_REQ, dl_err, (t_uscalar_t)err);
 641 }
 642 
 643 /*
 644  * DL_PROMISCOFF_REQ
 645  */
 646 static void
 647 proto_promiscoff_req(dld_str_t *dsp, mblk_t *mp)
 648 {
 649         dl_promiscoff_req_t *dlp = (dl_promiscoff_req_t *)mp->b_rptr;
 650         int             err = 0;
 651         t_uscalar_t     dl_err;
 652         uint32_t        new_flags;
 653         queue_t         *q = dsp->ds_wq;
 654         mac_perim_handle_t      mph;
 655 
 656         if (MBLKL(mp) < sizeof (dl_promiscoff_req_t)) {
 657                 dl_err = DL_BADPRIM;
 658                 goto failed;
 659         }
 660 
 661         if (dsp->ds_dlstate == DL_UNATTACHED ||
 662             DL_ACK_PENDING(dsp->ds_dlstate)) {
 663                 dl_err = DL_OUTSTATE;
 664                 goto failed;
 665         }
 666 
 667         mac_perim_enter_by_mh(dsp->ds_mh, &mph);
 668 
 669         new_flags = dsp->ds_promisc;
 670         switch (dlp->dl_level) {
 671         case DL_PROMISC_SAP:
 672                 if (!(dsp->ds_promisc & DLS_PROMISC_SAP)) {
 673                         dl_err = DL_NOTENAB;
 674                         goto failed;
 675                 }
 676                 new_flags &= ~DLS_PROMISC_SAP;
 677                 break;
 678 
 679         case DL_PROMISC_MULTI:
 680                 if (!(dsp->ds_promisc & DLS_PROMISC_MULTI)) {
 681                         dl_err = DL_NOTENAB;
 682                         goto failed;
 683                 }
 684                 new_flags &= ~DLS_PROMISC_MULTI;
 685                 break;
 686 
 687         case DL_PROMISC_PHYS:
 688                 if (!(dsp->ds_promisc & DLS_PROMISC_PHYS)) {
 689                         dl_err = DL_NOTENAB;
 690                         goto failed;
 691                 }
 692                 new_flags &= ~DLS_PROMISC_PHYS;
 693                 break;
 694 
 695         default:
 696                 dl_err = DL_NOTSUPPORTED;
 697                 goto failed;
 698         }
 699 

 700         /*
 701          * Adjust channel promiscuity.
 702          */
 703         err = dls_promisc(dsp, new_flags);
 704 
 705         if (err != 0) {
 706                 mac_perim_exit(mph);
 707                 dl_err = DL_SYSERR;
 708                 goto failed;
 709         }
 710 
 711         ASSERT(dsp->ds_promisc == new_flags);
 712         if (dsp->ds_promisc == 0)
 713                 dls_active_clear(dsp, B_FALSE);
 714 
 715         mac_perim_exit(mph);
 716 
 717         dlokack(q, mp, DL_PROMISCOFF_REQ);
 718         return;
 719 failed:
 720         dlerrorack(q, mp, DL_PROMISCOFF_REQ, dl_err, (t_uscalar_t)err);
 721 }
 722 
 723 /*
 724  * DL_ENABMULTI_REQ
 725  */
 726 static void
 727 proto_enabmulti_req(dld_str_t *dsp, mblk_t *mp)
 728 {
 729         dl_enabmulti_req_t *dlp = (dl_enabmulti_req_t *)mp->b_rptr;
 730         int             err = 0;
 731         t_uscalar_t     dl_err;