From owner-p4-projects@FreeBSD.ORG Thu Dec 2 05:31:10 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4D99D16A4D0; Thu, 2 Dec 2004 05:31:10 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2427316A4CE for ; Thu, 2 Dec 2004 05:31:10 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id E3D5C43D49 for ; Thu, 2 Dec 2004 05:31:09 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id iB25V9BA050400 for ; Thu, 2 Dec 2004 05:31:09 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id iB25V97X050397 for perforce@freebsd.org; Thu, 2 Dec 2004 05:31:09 GMT (envelope-from sam@freebsd.org) Date: Thu, 2 Dec 2004 05:31:09 GMT Message-Id: <200412020531.iB25V97X050397@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 66240 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Dec 2004 05:31:10 -0000 http://perforce.freebsd.org/chv.cgi?CH=66240 Change 66240 by sam@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.