On Wed, Apr 25, 2018 at 08:55:26PM +0300, Paul Irofti wrote:
> Hi,
> 
> The following diff removes the functionality of the SIOCS80211SCAN ioctl.
> After long discussions with stps@, mpi@, and deraadt@ we decided that
> this was the correct way of fixing ifconfig scan from blocking the
> network stack.
> 
> The kernel will continue scanning in the background and filling the
> nodes array, but ifconfig scan commands will now basically do just a
> SIOCG80211ALLNODES and pretty print the array. So the output stays the
> same but is instant.
> 
> In fact, when the interface is freshly brought up, if you type fast
> enough, you can see the array being filled by running multiple ifconfig
> scans in sequence.
> 
> Another change that this introduces is the fact that ifconfig scan no
> longer plays with UP and DOWN. If the interface is down it complains and
> exits. This is needed in order to maintain the nodes list.
> 
> Currently tested on iwm(4), urtwn(4), run(4) and athn(4). We are
> interested in wider testing, specially on iwn(4) and athn(4) in client
> mode.
> 
> Thoughts? OKs?
> 
> Paul

Updated diff that fixes scan on hostap mode. This removes the hostap
check from SIOCG80211ALLNODES that I added by mistake.


diff --git sbin/ifconfig/ifconfig.c sbin/ifconfig/ifconfig.c
index 993a1ed32c8..5643c1f0219 100644
--- sbin/ifconfig/ifconfig.c
+++ sbin/ifconfig/ifconfig.c
@@ -2255,11 +2255,11 @@ ieee80211_listnodes(void)
        struct ieee80211_nodereq_all na;
        struct ieee80211_nodereq nr[512];
        struct ifreq ifr;
-       int i, down = 0;
+       int i;
 
        if ((flags & IFF_UP) == 0) {
-               down = 1;
-               setifflags("up", IFF_UP);
+               printf("\t\tcan not scan, interface is down\n");
+               return;
        }
 
        bzero(&ifr, sizeof(ifr));
@@ -2268,7 +2268,7 @@ ieee80211_listnodes(void)
        if (ioctl(s, SIOCS80211SCAN, (caddr_t)&ifr) != 0) {
                if (errno == EPERM)
                        printf("\t\tno permission to scan\n");
-               goto done;
+               return;
        }
 
        bzero(&na, sizeof(na));
@@ -2279,7 +2279,7 @@ ieee80211_listnodes(void)
 
        if (ioctl(s, SIOCG80211ALLNODES, &na) != 0) {
                warn("SIOCG80211ALLNODES");
-               goto done;
+               return;
        }
 
        if (!na.na_nodes)
@@ -2292,10 +2292,6 @@ ieee80211_listnodes(void)
                ieee80211_printnode(&nr[i]);
                putchar('\n');
        }
-
- done:
-       if (down)
-               setifflags("restore", -IFF_UP);
 }
 
 void
diff --git sys/dev/ic/athn.c sys/dev/ic/athn.c
index 54f1e668f7d..0830049a401 100644
--- sys/dev/ic/athn.c
+++ sys/dev/ic/athn.c
@@ -2917,8 +2917,6 @@ athn_stop(struct ifnet *ifp, int disable)
        ifq_clr_oactive(&ifp->if_snd);
 
        timeout_del(&sc->scan_to);
-       /* In case we were scanning, release the scan "lock". */
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
 
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 
diff --git sys/dev/ic/bwfm.c sys/dev/ic/bwfm.c
index 8a2f1beaddd..b05427cc0b9 100644
--- sys/dev/ic/bwfm.c
+++ sys/dev/ic/bwfm.c
@@ -463,9 +463,6 @@ bwfm_stop(struct ifnet *ifp)
        ifp->if_flags &= ~IFF_RUNNING;
        ifq_clr_oactive(&ifp->if_snd);
 
-       /* In case we were scanning, release the scan "lock". */
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
-
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 
        bwfm_fwvar_cmd_set_int(sc, BWFM_C_DOWN, 1);
diff --git sys/dev/pci/if_ipw.c sys/dev/pci/if_ipw.c
index 57532466efd..a519af322ec 100644
--- sys/dev/pci/if_ipw.c
+++ sys/dev/pci/if_ipw.c
@@ -2024,9 +2024,6 @@ ipw_stop(struct ifnet *ifp, int disable)
        for (i = 0; i < IPW_NTBD; i++)
                ipw_release_sbd(sc, &sc->stbd_list[i]);
 
-       /* in case we were scanning, release the scan "lock" */
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
-
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 }
 
diff --git sys/dev/pci/if_iwi.c sys/dev/pci/if_iwi.c
index f60f9113333..c3801f008df 100644
--- sys/dev/pci/if_iwi.c
+++ sys/dev/pci/if_iwi.c
@@ -2291,9 +2291,6 @@ iwi_stop(struct ifnet *ifp, int disable)
        ifp->if_flags &= ~IFF_RUNNING;
        ifq_clr_oactive(&ifp->if_snd);
 
-       /* in case we were scanning, release the scan "lock" */
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
-
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 
        iwi_stop_master(sc);
diff --git sys/dev/pci/if_iwm.c sys/dev/pci/if_iwm.c
index fa3c1c82cc8..5a526802010 100644
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -6708,9 +6708,6 @@ iwm_stop(struct ifnet *ifp)
                sc->sc_cmd_resp_pkt[i] = NULL;
                sc->sc_cmd_resp_len[i] = 0;
        }
-       if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST)
-               wakeup(&ic->ic_scan_lock);
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
        ifp->if_flags &= ~IFF_RUNNING;
        ifq_clr_oactive(&ifp->if_snd);
 
diff --git sys/dev/pci/if_iwn.c sys/dev/pci/if_iwn.c
index d26fb6a5e64..a839000a2ae 100644
--- sys/dev/pci/if_iwn.c
+++ sys/dev/pci/if_iwn.c
@@ -6633,11 +6633,6 @@ iwn_stop(struct ifnet *ifp, int disable)
        ifp->if_flags &= ~IFF_RUNNING;
        ifq_clr_oactive(&ifp->if_snd);
 
-       /* In case we were scanning, release the scan "lock". */
-       if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST)
-               wakeup(&ic->ic_scan_lock);
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
-
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 
        /* Power OFF hardware. */
diff --git sys/dev/pci/if_wpi.c sys/dev/pci/if_wpi.c
index 214f1944ca3..0c5162b628c 100644
--- sys/dev/pci/if_wpi.c
+++ sys/dev/pci/if_wpi.c
@@ -3319,9 +3319,6 @@ wpi_stop(struct ifnet *ifp, int disable)
        ifp->if_flags &= ~IFF_RUNNING;
        ifq_clr_oactive(&ifp->if_snd);
 
-       /* In case we were scanning, release the scan "lock". */
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
-
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 
        /* Power OFF hardware. */
diff --git sys/dev/usb/if_rsu.c sys/dev/usb/if_rsu.c
index fb70699874e..f55f23d79ae 100644
--- sys/dev/usb/if_rsu.c
+++ sys/dev/usb/if_rsu.c
@@ -2313,9 +2313,6 @@ rsu_stop(struct ifnet *ifp)
        ifp->if_flags &= ~IFF_RUNNING;
        ifq_clr_oactive(&ifp->if_snd);
 
-       /* In case we were scanning, release the scan "lock". */
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
-
        s = splusb();
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
        /* Wait for all async commands to complete. */
diff --git sys/net80211/ieee80211.c sys/net80211/ieee80211.c
index da43082d70c..6f6db224727 100644
--- sys/net80211/ieee80211.c
+++ sys/net80211/ieee80211.c
@@ -143,7 +143,6 @@ ieee80211_channel_init(struct ifnet *ifp)
        if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0)
                ic->ic_curmode = IEEE80211_MODE_AUTO;
        ic->ic_des_chan = IEEE80211_CHAN_ANYC;  /* any channel is ok */
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
 }
 
 void
diff --git sys/net80211/ieee80211_ioctl.c sys/net80211/ieee80211_ioctl.c
index 4c8fb30f2b0..53613b7cbb3 100644
--- sys/net80211/ieee80211_ioctl.c
+++ sys/net80211/ieee80211_ioctl.c
@@ -670,42 +670,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t 
data)
                        ifp->if_mtu = ifr->ifr_mtu;
                break;
        case SIOCS80211SCAN:
-               if ((error = suser(curproc)) != 0)
-                       break;
-#ifndef IEEE80211_STA_ONLY
-               if (ic->ic_opmode == IEEE80211_M_HOSTAP)
-                       break;
-#endif
-               if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
-                   (IFF_UP | IFF_RUNNING)) {
-                       error = ENETDOWN;
-                       break;
-               }
-               if ((ic->ic_scan_lock & IEEE80211_SCAN_REQUEST) == 0) {
-                       if (ic->ic_scan_lock & IEEE80211_SCAN_LOCKED)
-                               ic->ic_scan_lock |= IEEE80211_SCAN_RESUME;
-                       ic->ic_scan_lock |= IEEE80211_SCAN_REQUEST;
-                       if (ic->ic_state != IEEE80211_S_SCAN) {
-                               ieee80211_clean_cached(ic);
-                               if (ic->ic_opmode == IEEE80211_M_STA &&
-                                   ic->ic_state == IEEE80211_S_RUN &&
-                                   IFM_MODE(ic->ic_media.ifm_cur->ifm_media)
-                                   == IFM_AUTO) {
-                                       /* 
-                                        * We're already associated to an AP.
-                                        * Make the scanning loop start off in
-                                        * auto mode so all supported bands
-                                        * get scanned.
-                                        */
-                                       ieee80211_setmode(ic,
-                                           IEEE80211_MODE_AUTO);
-                               }
-                               ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
-                       }
-               }
-               /* Let the userspace process wait for completion */
-               error = tsleep(&ic->ic_scan_lock, PCATCH, "80211scan",
-                   hz * IEEE80211_SCAN_TIMEOUT);
+               /* Disabled. SIOCG80211ALLNODES is enough. */
                break;
        case SIOCG80211NODE:
                nr = (struct ieee80211_nodereq *)data;
@@ -769,6 +734,12 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t 
data)
                break;
 #endif
        case SIOCG80211ALLNODES:
+               if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
+                   (IFF_UP | IFF_RUNNING)) {
+                       error = ENETDOWN;
+                       break;
+               }
+
                na = (struct ieee80211_nodereq_all *)data;
                na->na_nodes = i = 0;
                ni = RBT_MIN(ieee80211_tree, &ic->ic_tree);
diff --git sys/net80211/ieee80211_node.c sys/net80211/ieee80211_node.c
index ae923d5beef..0c238167a42 100644
--- sys/net80211/ieee80211_node.c
+++ sys/net80211/ieee80211_node.c
@@ -245,10 +245,6 @@ ieee80211_begin_scan(struct ifnet *ifp)
 {
        struct ieee80211com *ic = (void *)ifp;
 
-       if (ic->ic_scan_lock & IEEE80211_SCAN_LOCKED)
-               return;
-       ic->ic_scan_lock |= IEEE80211_SCAN_LOCKED;
-
        /*
         * In all but hostap mode scanning starts off in
         * an active mode before switching to passive.
@@ -709,7 +705,7 @@ ieee80211_end_scan(struct ifnet *ifp)
                                        break;
                }
                ieee80211_create_ibss(ic, &ic->ic_channels[i]);
-               goto wakeup;
+               return;
        }
 #endif
        if (ni == NULL) {
@@ -721,7 +717,7 @@ ieee80211_end_scan(struct ifnet *ifp)
                    (ic->ic_flags & IEEE80211_F_IBSSON) &&
                    ic->ic_des_esslen != 0) {
                        ieee80211_create_ibss(ic, ic->ic_ibss_chan);
-                       goto wakeup;
+                       return;
                }
 #endif
                /*
@@ -735,14 +731,8 @@ ieee80211_end_scan(struct ifnet *ifp)
                 */
                if (ieee80211_next_mode(ifp) == IEEE80211_MODE_AUTO ||
                    (ic->ic_caps & IEEE80211_C_SCANALLBAND)) {
-                       if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST &&
-                           ic->ic_scan_lock & IEEE80211_SCAN_RESUME) {
-                               ic->ic_scan_lock = IEEE80211_SCAN_LOCKED;
-                               /* Return from a user-initiated scan. */
-                               wakeup(&ic->ic_scan_lock);
-                       } else if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST)
-                               goto wakeup;
                        ic->ic_scan_count++;
+                       return;
                }
 
                /*
@@ -819,13 +809,13 @@ ieee80211_end_scan(struct ifnet *ifp)
                        if (ic->ic_bgscan_fail < IEEE80211_BGSCAN_FAIL_MAX)
                                ic->ic_bgscan_fail++;
                        ic->ic_flags &= ~IEEE80211_F_BGSCAN;
-                       goto wakeup;
+                       return;
                }
        
                arg = malloc(sizeof(*arg), M_DEVBUF, M_NOWAIT | M_ZERO);
                if (arg == NULL) {
                        ic->ic_flags &= ~IEEE80211_F_BGSCAN;
-                       goto wakeup;
+                       return;
                }
 
                ic->ic_bgscan_fail = 0;
@@ -838,7 +828,7 @@ ieee80211_end_scan(struct ifnet *ifp)
                    IEEE80211_FC0_SUBTYPE_DEAUTH,
                    IEEE80211_REASON_AUTH_LEAVE) != 0) {
                        ic->ic_flags &= ~IEEE80211_F_BGSCAN;
-                       goto wakeup;
+                       return;
                }
 
                /* Prevent dispatch of additional data frames to hardware. */
@@ -854,19 +844,11 @@ ieee80211_end_scan(struct ifnet *ifp)
                ic->ic_bss->ni_unref_arg_size = sizeof(*arg);
                ic->ic_bss->ni_unref_cb = ieee80211_node_switch_bss;
                /* F_BGSCAN flag gets cleared in ieee80211_node_join_bss(). */
-               goto wakeup;
+               return;
        } else if (selbs == NULL)
                goto notfound;
 
        ieee80211_node_join_bss(ic, selbs);
-
- wakeup:
-       if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST) {
-               /* Return from a user-initiated scan. */
-               wakeup(&ic->ic_scan_lock);
-       }
-
-       ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
 }
 
 /*
diff --git sys/net80211/ieee80211_var.h sys/net80211/ieee80211_var.h
index 5b9e11179dd..0772fb32791 100644
--- sys/net80211/ieee80211_var.h
+++ sys/net80211/ieee80211_var.h
@@ -240,7 +240,6 @@ struct ieee80211com {
        u_char                  ic_chan_scan[howmany(IEEE80211_CHAN_MAX,NBBY)];
        struct mbuf_queue       ic_mgtq;
        struct mbuf_queue       ic_pwrsaveq;
-       u_int                   ic_scan_lock;   /* user-initiated scan */
        u_int8_t                ic_scan_count;  /* count scans */
        u_int32_t               ic_flags;       /* state flags */
        u_int32_t               ic_xflags;      /* more flags */

Reply via email to