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
*/