Print this page
OS-6357 proto_promiscoff_req() doesn't always exit the MAC perimeter
        
*** 19,28 ****
--- 19,29 ----
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   * Copyright 2012, Nexenta Systems, Inc. All rights reserved.
+  * Copyright 2017 Joyent, Inc.
   */
  
  /*
   * Data-Link Driver
   */
*** 680,741 ****
          new_flags = dsp->ds_promisc;
          switch (dlp->dl_level) {
          case DL_PROMISC_SAP:
                  if (!(dsp->ds_promisc & DLS_PROMISC_SAP)) {
                          dl_err = DL_NOTENAB;
!                         goto failed;
                  }
                  new_flags &= ~DLS_PROMISC_SAP;
                  break;
  
          case DL_PROMISC_MULTI:
                  if (!(dsp->ds_promisc & DLS_PROMISC_MULTI)) {
                          dl_err = DL_NOTENAB;
!                         goto failed;
                  }
                  new_flags &= ~DLS_PROMISC_MULTI;
                  break;
  
          case DL_PROMISC_PHYS:
                  if (!(dsp->ds_promisc & DLS_PROMISC_PHYS)) {
                          dl_err = DL_NOTENAB;
!                         goto failed;
                  }
                  new_flags &= ~DLS_PROMISC_PHYS;
                  break;
  
          case DL_PROMISC_RX_ONLY:
                  if (!(dsp->ds_promisc & DLS_PROMISC_RX_ONLY)) {
                          dl_err = DL_NOTENAB;
!                         goto failed;
                  }
                  new_flags &= ~DLS_PROMISC_RX_ONLY;
                  break;
  
          case DL_PROMISC_FIXUPS:
                  if (!(dsp->ds_promisc & DLS_PROMISC_FIXUPS)) {
                          dl_err = DL_NOTENAB;
!                         goto failed;
                  }
                  new_flags &= ~DLS_PROMISC_FIXUPS;
                  break;
  
          default:
                  dl_err = DL_NOTSUPPORTED;
!                 mac_perim_exit(mph);
!                 goto failed;
          }
  
          /*
           * Adjust channel promiscuity.
           */
          err = dls_promisc(dsp, new_flags);
  
          if (err != 0) {
-                 mac_perim_exit(mph);
                  dl_err = DL_SYSERR;
!                 goto failed;
          }
  
          ASSERT(dsp->ds_promisc == new_flags);
          if (dsp->ds_promisc == 0)
                  dls_active_clear(dsp, B_FALSE);
--- 681,740 ----
          new_flags = dsp->ds_promisc;
          switch (dlp->dl_level) {
          case DL_PROMISC_SAP:
                  if (!(dsp->ds_promisc & DLS_PROMISC_SAP)) {
                          dl_err = DL_NOTENAB;
!                         goto failed2;
                  }
                  new_flags &= ~DLS_PROMISC_SAP;
                  break;
  
          case DL_PROMISC_MULTI:
                  if (!(dsp->ds_promisc & DLS_PROMISC_MULTI)) {
                          dl_err = DL_NOTENAB;
!                         goto failed2;
                  }
                  new_flags &= ~DLS_PROMISC_MULTI;
                  break;
  
          case DL_PROMISC_PHYS:
                  if (!(dsp->ds_promisc & DLS_PROMISC_PHYS)) {
                          dl_err = DL_NOTENAB;
!                         goto failed2;
                  }
                  new_flags &= ~DLS_PROMISC_PHYS;
                  break;
  
          case DL_PROMISC_RX_ONLY:
                  if (!(dsp->ds_promisc & DLS_PROMISC_RX_ONLY)) {
                          dl_err = DL_NOTENAB;
!                         goto failed2;
                  }
                  new_flags &= ~DLS_PROMISC_RX_ONLY;
                  break;
  
          case DL_PROMISC_FIXUPS:
                  if (!(dsp->ds_promisc & DLS_PROMISC_FIXUPS)) {
                          dl_err = DL_NOTENAB;
!                         goto failed2;
                  }
                  new_flags &= ~DLS_PROMISC_FIXUPS;
                  break;
  
          default:
                  dl_err = DL_NOTSUPPORTED;
!                 goto failed2;
          }
  
          /*
           * Adjust channel promiscuity.
           */
          err = dls_promisc(dsp, new_flags);
  
          if (err != 0) {
                  dl_err = DL_SYSERR;
!                 goto failed2;
          }
  
          ASSERT(dsp->ds_promisc == new_flags);
          if (dsp->ds_promisc == 0)
                  dls_active_clear(dsp, B_FALSE);
*** 742,751 ****
--- 741,752 ----
  
          mac_perim_exit(mph);
  
          dlokack(q, mp, DL_PROMISCOFF_REQ);
          return;
+ failed2:
+         mac_perim_exit(mph);
  failed:
          dlerrorack(q, mp, DL_PROMISCOFF_REQ, dl_err, (t_uscalar_t)err);
  }
  
  /*