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