PERFORCE change 66240 for review
Sam Leffler
sam at FreeBSD.org
Wed Dec 1 21:31:10 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=66240
Change 66240 by sam at sam_ebb on 2004/12/02 05:30:51
Revamp sta inactivity handling:
o set a reload value in each node that's loaded into ni_inact
on frame rx (rather than sprinkling reloads around)
o have ath driver reload ni_inact on notice of frame ACK (need
to update other drivers)
o add an inactivity probe threshold, when it's hit we send a
null data frame which should be ack'd and reset ni_inact
o add mib variable for inact_probe
This eliminates gratuitous station deauthentication which is
important when authenticated with WPA/802.1x.
Affected files ...
.. //depot/projects/wifi/sys/dev/ath/if_ath.c#36 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_freebsd.c#6 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#21 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#22 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.h#15 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_output.c#18 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#14 edit
Differences ...
==== //depot/projects/wifi/sys/dev/ath/if_ath.c#36 (text+ko) ====
@@ -3353,6 +3353,7 @@
pri = M_WME_GETAC(bf->bf_m);
if (pri >= WME_AC_VO)
ic->ic_wme.wme_hipri_traffic++;
+ ni->ni_inact = ni->ni_inact_reload;
} else {
if (ds->ds_txstat.ts_status & HAL_TXERR_XRETRY)
sc->sc_stats.ast_tx_xretries++;
==== //depot/projects/wifi/sys/net80211/ieee80211_freebsd.c#6 (text+ko) ====
@@ -110,6 +110,10 @@
ieee80211_sysctl_inact, "I",
"station inactivity timeout (sec)");
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "inact_probe", CTLTYPE_INT | CTLFLAG_RW, &ic->ic_inact_probe, 0,
+ ieee80211_sysctl_inact, "I",
+ "station inactivity probe timeout (sec)");
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
"inact_auth", CTLTYPE_INT | CTLFLAG_RW, &ic->ic_inact_auth, 0,
ieee80211_sysctl_inact, "I",
"station authentication timeout (sec)");
==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#21 (text+ko) ====
@@ -119,6 +119,7 @@
u_int16_t rxseq;
KASSERT(ni != NULL, ("null node"));
+ ni->ni_inact = ni->ni_inact_reload;
/* trim CRC here so WEP can find its own CRC at the end of packet. */
if (m->m_flags & M_HASFCS) {
@@ -458,7 +459,6 @@
IEEE80211_NODE_STAT(ni, rx_unauth);
goto err;
}
- ni->ni_inact = ic->ic_inact_auth;
} else {
/*
* When denying unencrypted frames, discard
@@ -474,7 +474,6 @@
IEEE80211_NODE_STAT(ni, rx_unencrypted);
goto out;
}
- ni->ni_inact = ic->ic_inact_run;
}
ifp->if_ipackets++;
IEEE80211_NODE_STAT(ni, rx_data);
@@ -866,8 +865,7 @@
if (ni == NULL)
return;
}
- ni->ni_rssi = rssi;
- ni->ni_rstamp = rstamp;
+ ni->ni_inact_reload = ic->ic_inact_auth;
IEEE80211_SEND_MGMT(ic, ni,
IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
@@ -1049,6 +1047,7 @@
estatus = IEEE80211_STATUS_CHALLENGE;
goto bad;
}
+ ni->ni_inact_reload = ic->ic_inact_auth;
IEEE80211_DPRINTF(ic,
IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
"station %s authenticated (shared key)\n",
@@ -1832,7 +1831,6 @@
}
if (wme != NULL && ieee80211_parse_wmeparams(ic, wme))
ieee80211_wme_updateparams(ic);
- ni->ni_inact = ic->ic_inact_run;
/* NB: don't need the rest of this */
return;
}
@@ -1863,26 +1861,23 @@
ni->ni_esslen = ssid[1];
memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
memcpy(ni->ni_essid, ssid + 2, ssid[1]);
- } else {
- ni->ni_inact = ic->ic_inact_run; /* XXX? */
- if (ssid[1] != 0 &&
- (ISPROBE(subtype) || ni->ni_esslen == 0)) {
- /*
- * Update ESSID at probe response to adopt
- * hidden AP by Lucent/Cisco, which announces
- * null ESSID in beacon.
- */
+ } else if (ssid[1] != 0 &&
+ (ISPROBE(subtype) || ni->ni_esslen == 0)) {
+ /*
+ * Update ESSID at probe response to adopt
+ * hidden AP by Lucent/Cisco, which announces
+ * null ESSID in beacon.
+ */
#ifdef IEEE80211_DEBUG
- if (ieee80211_msg_scan(ic) ||
- ieee80211_msg_debug(ic))
- dump_probe_beacon(subtype, 0,
- wh->i_addr2, chan, bchan, capinfo,
- bintval, erp, ssid, country);
+ if (ieee80211_msg_scan(ic) ||
+ ieee80211_msg_debug(ic))
+ dump_probe_beacon(subtype, 0,
+ wh->i_addr2, chan, bchan, capinfo,
+ bintval, erp, ssid, country);
#endif
- ni->ni_esslen = ssid[1];
- memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
- memcpy(ni->ni_essid, ssid + 2, ssid[1]);
- }
+ ni->ni_esslen = ssid[1];
+ memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
+ memcpy(ni->ni_essid, ssid + 2, ssid[1]);
}
ni->ni_scangen = ic->ic_scan.nt_scangen;
IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
@@ -2371,7 +2366,6 @@
ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : ""
);
- ni->ni_inact = ic->ic_inact_run;
ieee80211_new_state(ic, IEEE80211_S_RUN, subtype);
break;
}
@@ -2393,7 +2387,6 @@
IEEE80211_NODE_STAT(ni, rx_deauth);
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
- ni->ni_inact = ic->ic_inact_run;
ieee80211_new_state(ic, IEEE80211_S_AUTH,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
@@ -2431,7 +2424,6 @@
IEEE80211_NODE_STAT(ni, rx_disassoc);
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
- ni->ni_inact = ic->ic_inact_run;
ieee80211_new_state(ic, IEEE80211_S_ASSOC,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
@@ -2555,7 +2547,6 @@
IEEE80211_REASON_NOT_ASSOCED);
return;
}
- ni->ni_inact = ic->ic_inact_run;
/* Okay, take the first queued packet and put it out... */
IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen);
==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#22 (text+ko) ====
@@ -92,6 +92,7 @@
ic->ic_inact_init = IEEE80211_INACT_INIT;
ic->ic_inact_auth = IEEE80211_INACT_AUTH;
ic->ic_inact_run = IEEE80211_INACT_RUN;
+ ic->ic_inact_probe = IEEE80211_INACT_PROBE;
/* XXX defer */
if (ic->ic_max_aid == 0)
@@ -906,7 +907,7 @@
ni->ni_authmode = IEEE80211_AUTH_OPEN;
ni->ni_txpower = ic->ic_txpowlimit; /* max power */
ieee80211_crypto_resetkey(ic, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE);
- ni->ni_inact = nt->nt_inact_init;
+ ni->ni_inact = ni->ni_inact_reload = nt->nt_inact_init;
IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");
IEEE80211_NODE_LOCK(nt);
@@ -1400,6 +1401,21 @@
ic->ic_set_tim(ic, ni, 0);
}
}
+ /*
+ * Probe the station before time it out. We
+ * send a null data frame which may not be
+ * universally supported by drivers (need it
+ * for ps-poll support so it should be...).
+ */
+ if (ni->ni_inact == ic->ic_inact_probe) {
+ IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
+ "[%s] probe station due to inactivity\n",
+ ether_sprintf(ni->ni_macaddr));
+ IEEE80211_NODE_UNLOCK(nt);
+ ieee80211_send_nulldata(ic, ni);
+ /* XXX stat? */
+ goto restart;
+ }
}
if (ni->ni_inact <= 0) {
IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
@@ -1599,6 +1615,7 @@
/* give driver a chance to setup state like ni_txrate */
if (ic->ic_newassoc)
ic->ic_newassoc(ic, ni, newassoc);
+ ni->ni_inact_reload = ic->ic_inact_run;
IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS);
/* tell the authenticator about new station */
if (ic->ic_auth->ia_node_join != NULL)
@@ -1711,6 +1728,7 @@
*/
ieee80211_sta_leave(ic, ni);
done:
+ ni->ni_inact_reload = ic->ic_inact_init; /* just in case */
ieee80211_free_node(ni);
}
==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#15 (text+ko) ====
@@ -55,6 +55,7 @@
#define IEEE80211_INACT_INIT (30/IEEE80211_INACT_WAIT) /* initial */
#define IEEE80211_INACT_AUTH (180/IEEE80211_INACT_WAIT) /* associated but not authorized */
#define IEEE80211_INACT_RUN (300/IEEE80211_INACT_WAIT) /* authorized */
+#define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT) /* probe */
#define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT) /* scanned */
#define IEEE80211_TRANS_WAIT 5 /* mgt frame tx timer (secs) */
@@ -138,7 +139,8 @@
/* others */
int ni_fails; /* failure count to associate */
- int ni_inact; /* inactivity mark count */
+ short ni_inact; /* inactivity mark count */
+ short ni_inact_reload;/* inactivity reload value */
int ni_txrate; /* index to ni_rates[] */
struct ifqueue ni_savedq; /* ps-poll queue */
struct ieee80211_nodestats ni_stats; /* per-node statistics */
==== //depot/projects/wifi/sys/net80211/ieee80211_output.c#18 (text+ko) ====
@@ -554,19 +554,6 @@
ni->ni_txseqs[0]++;
}
- if (eh.ether_type != htons(ETHERTYPE_PAE)) {
- /*
- * Reset the inactivity timer only for non-PAE traffic
- * to avoid a problem where the station leaves w/o
- * notice while we're requesting Identity. In this
- * situation the 802.1x state machine will continue
- * to retransmit the requests because it assumes the
- * station will be timed out for inactivity, but our
- * retransmits will reset the inactivity timer.
- */
- ni->ni_inact = ic->ic_inact_run;
- }
-
IEEE80211_NODE_STAT(ni, tx_data);
IEEE80211_NODE_STAT_ADD(ni, tx_bytes, datalen);
==== //depot/projects/wifi/sys/net80211/ieee80211_var.h#14 (text+ko) ====
@@ -148,6 +148,7 @@
int ic_inact_init; /* initial setting */
int ic_inact_auth; /* auth but not assoc setting */
int ic_inact_run; /* authorized setting */
+ int ic_inact_probe; /* inactive probe time */
/*
* WME/WMM state.
More information about the p4-projects
mailing list