This adds a new nwflag which can be used to disable roaming
between APs (i.e. disable background scanning) with ifconfig.

Currently, the only way to disable background scans is to hard-code
the BSSID of an access point. We can provide a more obvious toggle
for rare situations where APs are known to have trouble with clients
entering powersave mode (iwm and iwn will pretend to be in powersave
mode while a background scan is in progress).

Unfortunately, the 802.11 standard seems to provide no capability flag which
APs could use to tell clients that PS-poll based powersaving is not allowed.
So while I don't like knobs in general, I am willing to make an exception
for this one because I cannot find a good heuristic to use.

This diff repurposes the existing IEEE80211_F_ROAMING flag which was so
far unused. Moving this flag to nwflags means there is no ABI break.
ifconfig will only have to be recompiled with the new ieee80211_ioctl.h
to make use of the new flag. Still, if this is the wrong time in the
release cycle for such changes I will shelve this for later.

diff de1028205779e8bcaf24aad260046c98a79b637c 
e17574f85785da4fa4073c8b9a00d8d738f3298f
blob - 79a5adcd2197d91d9780f29a2c97a091b9177389
blob + 144a151a988f379d91775664e70500c708b17867
--- sbin/ifconfig/ifconfig.8
+++ sbin/ifconfig/ifconfig.8
@@ -1025,6 +1025,11 @@ This flag should only be used on wifi networks which a
 attacked with spoofed deauth frames.
 It breaks interoperability with spectrum management solutions and access
 points that perform band-steering of clients.
+.It roaming
+The
+.Ql roaming
+flag enables roaming between access points with the same NWID/ESSID.
+This flag is set by default if the driver supports roaming.
 .El
 .Pp
 Note that the
blob - 94d4f26f861d619c9a6e02b0e8e3bfcb2abd421f
blob + 2f24741993668d14abf1d74f9ae77861e9595161
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -7810,6 +7810,7 @@ iwm_attach(struct device *parent, struct device *self,
 
        ic->ic_node_alloc = iwm_node_alloc;
        ic->ic_bgscan_start = iwm_bgscan;
+       ic->ic_userflags |= IEEE80211_F_ROAMING;
 
        /* Override 802.11 state transition machine. */
        sc->sc_newstate = ic->ic_newstate;
blob - e9ca16a6f822b2e3bae8a087f245d4cc8e3d74fa
blob + 6beee6ec17830e1d98d1d5602ae2a5a06eba0faf
--- sys/dev/pci/if_iwn.c
+++ sys/dev/pci/if_iwn.c
@@ -531,6 +531,7 @@ iwn_attach(struct device *parent, struct device *self,
        ieee80211_ifattach(ifp);
        ic->ic_node_alloc = iwn_node_alloc;
        ic->ic_bgscan_start = iwn_bgscan;
+       ic->ic_userflags |= IEEE80211_F_ROAMING;
        ic->ic_newassoc = iwn_newassoc;
        ic->ic_updateedca = iwn_updateedca;
        ic->ic_set_key = iwn_set_key;
blob - ace97a38cc4ff76b454c1f6a12655565ad131275
blob + 4c033844ec5c29b89e8233ada29d258c0740a1eb
--- sys/net80211/ieee80211.c
+++ sys/net80211/ieee80211.c
@@ -75,6 +75,7 @@ ieee80211_begin_bgscan(struct ifnet *ifp)
        struct ieee80211com *ic = (void *)ifp;
 
        if ((ic->ic_flags & IEEE80211_F_BGSCAN) ||
+           (ic->ic_userflags & IEEE80211_F_ROAMING) == 0 ||
            ic->ic_state != IEEE80211_S_RUN || ic->ic_mgt_timer != 0)
                return;
 
blob - 6e192cfb3abd2224f7c1ae81c4fa43dbab8e9cb7
blob + 89e291d39fa988f200ace6680ef2a22f2d5a3e07
--- sys/net80211/ieee80211_input.c
+++ sys/net80211/ieee80211_input.c
@@ -299,7 +299,8 @@ ieee80211_inputm(struct ifnet *ifp, struct mbuf *m, st
                                timeout_del(&ic->ic_bgscan_timeout);
                        else if (!timeout_pending(&ic->ic_bgscan_timeout) &&
                            (ic->ic_flags & IEEE80211_F_BGSCAN) == 0 &&
-                           (ic->ic_flags & IEEE80211_F_DESBSSID) == 0)
+                           (ic->ic_flags & IEEE80211_F_DESBSSID) == 0 &&
+                           (ic->ic_userflags & IEEE80211_F_ROAMING))
                                timeout_add_msec(&ic->ic_bgscan_timeout,
                                    500 * (ic->ic_bgscan_fail + 1));
                }
blob - 94931282fe5196346946000597c4049c12b60fee
blob + e6a4f8559cd4599ca1d04be81cdd9c6bb0567b9c
--- sys/net80211/ieee80211_ioctl.h
+++ sys/net80211/ieee80211_ioctl.h
@@ -412,7 +412,8 @@ struct ieee80211_nodereq_all {
 #define IEEE80211_F_NOBRIDGE   0x00000002      /* CONF: no internal bridging */
 #define IEEE80211_F_HOSTAPMASK 0x00000003
 #define IEEE80211_F_STAYAUTH   0x00000004      /* CONF: ignore deauth */
-#define IEEE80211_F_USERBITS   "\20\01HIDENWID\02NOBRIDGE\03STAYAUTH"
+#define IEEE80211_F_ROAMING    0x00000008      /* CONF: roam between APs */
+#define IEEE80211_F_USERBITS   "\20\01HIDENWID\02NOBRIDGE\03STAYAUTH\04ROAMING"
 
 struct ieee80211_flags {
        const char              *f_name;
@@ -422,7 +423,8 @@ struct ieee80211_flags {
 #define IEEE80211_FLAGS        {                       \
        { "hidenwid", IEEE80211_F_HIDENWID },   \
        { "nobridge", IEEE80211_F_NOBRIDGE },   \
-       { "stayauth", IEEE80211_F_STAYAUTH }    \
+       { "stayauth", IEEE80211_F_STAYAUTH },   \
+       { "roaming", IEEE80211_F_ROAMING }      \
 }
 
 #define SIOCG80211FLAGS                _IOWR('i', 216, struct ifreq)
blob - 2a567a01422aaaf6024b05c5589f6f45b3744100
blob + 0f2072288232ac276c2979b799b03c37e0ca8032
--- sys/net80211/ieee80211_var.h
+++ sys/net80211/ieee80211_var.h
@@ -378,7 +378,6 @@ struct ieee80211_ess {
 #define        IEEE80211_F_IBSSON      0x00000200      /* CONF: IBSS creation 
enable */
 #define        IEEE80211_F_PMGTON      0x00000400      /* CONF: Power mgmt 
enable */
 #define        IEEE80211_F_DESBSSID    0x00000800      /* CONF: des_bssid is 
set */
-#define        IEEE80211_F_ROAMING     0x00002000      /* CONF: roaming 
enabled */
 #define        IEEE80211_F_TXPMGT      0x00018000      /* STATUS: tx power */
 #define IEEE80211_F_TXPOW_OFF  0x00000000      /* TX Power: radio disabled */
 #define IEEE80211_F_TXPOW_FIXED        0x00008000      /* TX Power: fixed rate 
*/

Reply via email to