Scale the missed beacon counter threshold to the AP's beacon interval.
authorstsp <stsp@openbsd.org>
Fri, 2 Jun 2017 15:31:26 +0000 (15:31 +0000)
committerstsp <stsp@openbsd.org>
Fri, 2 Jun 2017 15:31:26 +0000 (15:31 +0000)
This should make fading APs time out consistently regardless of what the
beacon interval is set to (range is 1 to 2^16 TU, though in practice 100 TU
seems to be a common value).

Print the beacon interval and missed beacon counter threshold to dmesg
if the DEBUG flag was set on the wireless interface with ifconfig(8).
This should help with diagnosing any issues that pop up.

Requested and diff eye-balled by kettenis@
help & ok tb@ phessler@

sys/net80211/ieee80211_proto.c

index fde740f..52f514f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_proto.c,v 1.75 2017/05/30 10:50:33 stsp Exp $       */
+/*     $OpenBSD: ieee80211_proto.c,v 1.76 2017/06/02 15:31:26 stsp Exp $       */
 /*     $NetBSD: ieee80211_proto.c,v 1.8 2004/04/30 23:58:20 dyoung Exp $       */
 
 /*-
@@ -76,6 +76,7 @@ const char * const ieee80211_phymode_name[] = {
        "11n",          /* IEEE80211_MODE_11N */
 };
 
+void ieee80211_set_beacon_miss_threshold(struct ieee80211com *);
 int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int);
 
 void
@@ -811,6 +812,27 @@ ieee80211_auth_open(struct ieee80211com *ic, const struct ieee80211_frame *wh,
        }
 }
 
+void
+ieee80211_set_beacon_miss_threshold(struct ieee80211com *ic)
+{
+       struct ifnet *ifp = &ic->ic_if;
+
+       /* 
+        * Scale the missed beacon counter threshold to the AP's actual
+        * beacon interval. Give the AP at least 700 ms to time out and
+        * round up to ensure that at least one beacon may be missed.
+        */
+       int btimeout = MIN(7 * ic->ic_bss->ni_intval, 700);
+       btimeout = MAX(btimeout, 2 * ic->ic_bss->ni_intval);
+       if (ic->ic_bss->ni_intval > 0) /* don't crash if interval is bogus */
+               ic->ic_bmissthres = btimeout / ic->ic_bss->ni_intval;
+
+       if (ifp->if_flags & IFF_DEBUG)
+               printf("%s: missed beacon threshold set to %d beacons, "
+                   "beacon interval is %u TU\n", ifp->if_xname,
+                   ic->ic_bmissthres, ic->ic_bss->ni_intval);
+}
+
 int
 ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate,
     int mgt)
@@ -1057,6 +1079,7 @@ justcleanup:
                                ieee80211_set_link_state(ic, LINK_STATE_UP);
                        }
                        ic->ic_mgt_timer = 0;
+                       ieee80211_set_beacon_miss_threshold(ic);
                        if_start(ifp);
                        break;
                }