Date: Thu, 7 Aug 2003 14:33:35 -0700 (PDT) From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 35734 for review Message-ID: <200308072133.h77LXZbB020498@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=35734 Change 35734 by sam@sam_ebb on 2003/08/07 14:32:45 Revamp input path: o driver is now expected to find the node associated with the sender of a received frame; use ic_bss if none is located o driver passes the (referenced) node into ieee80211_input for use within the wlan module and is responsible for cleaning up on return o the antenna state is no longer passed up with each frame; this is now considered driver-private state and drivers are responsible for keeping it in the driver-private part of a node This change reduces the number of node lookups from 2-4 to 1. May want to introduce some "convenience functions" in the wlan layer for use by drivers as this introduces a fair amount of code in each driver. May want to interpret a null node pointer in ieee80211_input as an indictor that the wlan module should lookup a node as before for drivers that don't need a reference to the node to record private state. Affected files ... .. //depot/projects/netperf/sys/net80211/ieee80211_input.c#2 edit .. //depot/projects/netperf/sys/net80211/ieee80211_node.c#3 edit .. //depot/projects/netperf/sys/net80211/ieee80211_node.h#3 edit .. //depot/projects/netperf/sys/net80211/ieee80211_proto.h#2 edit .. //depot/projects/netperf/sys/net80211/ieee80211_var.h#2 edit Differences ... ==== //depot/projects/netperf/sys/net80211/ieee80211_input.c#2 (text+ko) ==== @@ -66,12 +66,21 @@ #include <netinet/if_ether.h> #endif +/* + * Process a received frame. The node associated with the sender + * should be supplied. If nothing was found in the node table then + * the caller is assumed to supply a reference to ic_bss instead. + * The RSSI and a timestamp are also supplied. The RSSI data is used + * during AP scanning to select a AP to associate with; it can have + * any units so long as values have consistent units and higher values + * mean ``better signal''. The receive timestamp is currently not used + * by the 802.11 layer. + */ void -ieee80211_input(struct ifnet *ifp, struct mbuf *m, - int rssi, u_int32_t rstamp, u_int rantenna) +ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni, + int rssi, u_int32_t rstamp) { struct ieee80211com *ic = (void *)ifp; - struct ieee80211_node *ni = NULL; struct ieee80211_frame *wh; struct ether_header *eh; struct mbuf *m1; @@ -80,6 +89,8 @@ u_int8_t *bssid; u_int16_t rxseq; + KASSERT(ni != NULL, ("null node")); + /* trim CRC here for WEP can find its own CRC at the end of packet. */ if (m->m_flags & M_HASFCS) { m_adj(m, -IEEE80211_CRC_LEN); @@ -92,6 +103,7 @@ if (ifp->if_flags & IFF_DEBUG) if_printf(ifp, "receive packet with wrong version: %x\n", wh->i_fc[0]); + ieee80211_unref_node(&ni); goto err; } @@ -100,13 +112,11 @@ if (ic->ic_state != IEEE80211_S_SCAN) { switch (ic->ic_opmode) { case IEEE80211_M_STA: - ni = ieee80211_ref_node(ic->ic_bss); if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) { IEEE80211_DPRINTF2(("%s: discard frame from " "bss %s\n", __func__, ether_sprintf(wh->i_addr2))); /* not interested in */ - ieee80211_unref_node(&ni); goto out; } break; @@ -124,19 +134,6 @@ __func__, ether_sprintf(wh->i_addr3))); goto out; } - ni = ieee80211_find_node(ic, wh->i_addr2); - if (ni == NULL) { - IEEE80211_DPRINTF2(("%s: warning, unknown src " - "%s\n", __func__, - ether_sprintf(wh->i_addr2))); - /* - * NB: Node allocation is handled in the - * management handling routines. Just fake - * up a reference to the hosts's node to do - * the stuff below. - */ - ni = ieee80211_ref_node(ic->ic_bss); - } break; case IEEE80211_M_MONITOR: /* NB: this should collect everything */ @@ -147,7 +144,6 @@ } ni->ni_rssi = rssi; ni->ni_rstamp = rstamp; - ni->ni_rantenna = rantenna; rxseq = ni->ni_rxseq; ni->ni_rxseq = le16toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; @@ -155,11 +151,9 @@ if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && rxseq == ni->ni_rxseq) { /* duplicate, silently discarded */ - ieee80211_unref_node(&ni); goto out; } ni->ni_inact = 0; - ieee80211_unref_node(&ni); } switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { @@ -189,11 +183,11 @@ if (dir != IEEE80211_FC1_DIR_TODS) goto out; /* check if source STA is associated */ - ni = ieee80211_find_node(ic, wh->i_addr2); - if (ni == NULL) { + if (ni == ic->ic_bss) { IEEE80211_DPRINTF(("%s: data from unknown src " "%s\n", __func__, ether_sprintf(wh->i_addr2))); + /* NB: caller deals with reference */ ni = ieee80211_dup_bss(ic, wh->i_addr2); if (ni != NULL) { IEEE80211_SEND_MGMT(ic, ni, @@ -213,7 +207,6 @@ ieee80211_unref_node(&ni); goto err; } - ieee80211_unref_node(&ni); break; case IEEE80211_M_MONITOR: break; @@ -318,7 +311,7 @@ } if (ic->ic_rawbpf) bpf_mtap(ic->ic_rawbpf, m); - (*ic->ic_recv_mgmt)(ic, m, subtype, rssi, rstamp, rantenna); + (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); m_freem(m); return; @@ -499,13 +492,13 @@ } while (0) void -ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, - int rssi, u_int32_t rstamp, u_int rantenna) +ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, + struct ieee80211_node *ni, + int subtype, int rssi, u_int32_t rstamp) { #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) struct ifnet *ifp = &ic->ic_if; struct ieee80211_frame *wh; - struct ieee80211_node *ni; u_int8_t *frm, *efrm; u_int8_t *ssid, *rates, *xrates; int reassoc, resp, newassoc, allocbs; @@ -672,7 +665,6 @@ IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); ni->ni_rssi = rssi; ni->ni_rstamp = rstamp; - ni->ni_rantenna = rantenna; memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp)); ni->ni_intval = le16toh(*(u_int16_t *)bintval); ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo); @@ -731,8 +723,7 @@ return; } - ni = ieee80211_find_node(ic, wh->i_addr2); - if (ni == NULL) { + if (ni == ic->ic_bss) { ni = ieee80211_dup_bss(ic, wh->i_addr2); if (ni == NULL) return; @@ -743,7 +734,6 @@ allocbs = 0; ni->ni_rssi = rssi; ni->ni_rstamp = rstamp; - ni->ni_rantenna = rantenna; rate = ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); @@ -754,10 +744,12 @@ IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0); } - if (allocbs && ic->ic_opmode == IEEE80211_M_HOSTAP) - ieee80211_free_node(ic, ni); - else - ieee80211_unref_node(&ni); + if (allocbs) { + if (ic->ic_opmode == IEEE80211_M_HOSTAP) + ieee80211_free_node(ic, ni); + else + ieee80211_unref_node(&ni); + } break; } @@ -795,25 +787,24 @@ case IEEE80211_M_HOSTAP: if (ic->ic_state != IEEE80211_S_RUN || seq != 1) return; - allocbs = 0; - ni = ieee80211_find_node(ic, wh->i_addr2); - if (ni == NULL) { + if (ni == ic->ic_bss) { ni = ieee80211_alloc_node(ic, wh->i_addr2); if (ni == NULL) return; IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); ni->ni_rssi = rssi; ni->ni_rstamp = rstamp; - ni->ni_rantenna = rantenna; ni->ni_chan = ic->ic_bss->ni_chan; allocbs = 1; - } + } else + allocbs = 0; IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_AUTH, 2); if (ifp->if_flags & IFF_DEBUG) if_printf(ifp, "station %s %s authenticated\n", (allocbs ? "newly" : "already"), ether_sprintf(ni->ni_macaddr)); - ieee80211_unref_node(&ni); + if (allocbs) + ieee80211_unref_node(&ni); break; case IEEE80211_M_STA: @@ -824,11 +815,8 @@ "authentication failed (reason %d) for %s\n", status, ether_sprintf(wh->i_addr3)); - ni = ieee80211_find_node(ic, wh->i_addr2); - if (ni != NULL) { + if (ni != ic->ic_bss) ni->ni_fails++; - ieee80211_unref_node(&ni); - } return; } ieee80211_new_state(ic, IEEE80211_S_ASSOC, @@ -902,16 +890,16 @@ #endif return; } - ni = ieee80211_find_node(ic, wh->i_addr2); - if (ni == NULL) { + if (ni == ic->ic_bss) { IEEE80211_DPRINTF(("%s: not authenticated for %s\n", __func__, ether_sprintf(wh->i_addr2))); ni = ieee80211_dup_bss(ic, wh->i_addr2); - if (ni == NULL) - return; - IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, - IEEE80211_REASON_ASSOC_NOT_AUTHED); - ieee80211_free_node(ic, ni); + if (ni != NULL) { + IEEE80211_SEND_MGMT(ic, ni, + IEEE80211_FC0_SUBTYPE_DEAUTH, + IEEE80211_REASON_ASSOC_NOT_AUTHED); + ieee80211_free_node(ic, ni); + } return; } /* XXX per-node cipher suite */ @@ -925,7 +913,6 @@ __func__, capinfo, ether_sprintf(wh->i_addr2))); ni->ni_associd = 0; IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_CAPINFO); - ieee80211_unref_node(&ni); return; } ieee80211_setup_rates(ic, ni, rates, xrates, @@ -936,12 +923,10 @@ __func__, ether_sprintf(wh->i_addr2))); ni->ni_associd = 0; IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_BASIC_RATE); - ieee80211_unref_node(&ni); return; } ni->ni_rssi = rssi; ni->ni_rstamp = rstamp; - ni->ni_rantenna = rantenna; ni->ni_intval = bintval; ni->ni_capinfo = capinfo; ni->ni_chan = ic->ic_bss->ni_chan; @@ -964,7 +949,6 @@ /* give driver a chance to setup state like ni_txrate */ if (ic->ic_newassoc) (*ic->ic_newassoc)(ic, ni, newassoc); - ieee80211_unref_node(&ni); break; } @@ -994,11 +978,8 @@ if (status != 0) { if_printf(ifp, "association failed (reason %d) for %s\n", status, ether_sprintf(wh->i_addr3)); - ni = ieee80211_find_node(ic, wh->i_addr2); - if (ni != NULL) { + if (ni != ic->ic_bss) ni->ni_fails++; - ieee80211_unref_node(&ni); - } return; } ni->ni_associd = le16toh(*(u_int16_t *)frm); @@ -1041,13 +1022,13 @@ wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); break; case IEEE80211_M_HOSTAP: - ni = ieee80211_find_node(ic, wh->i_addr2); - if (ni != NULL) { + if (ni != ic->ic_bss) { if (ifp->if_flags & IFF_DEBUG) if_printf(ifp, "station %s deauthenticated" " by peer (reason %d)\n", ether_sprintf(ni->ni_macaddr), reason); - ieee80211_free_node(ic, ni); + /* node will be free'd on return */ + ieee80211_unref_node(&ni); } break; default: @@ -1070,14 +1051,13 @@ wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); break; case IEEE80211_M_HOSTAP: - ni = ieee80211_find_node(ic, wh->i_addr2); - if (ni != NULL) { + if (ni != ic->ic_bss) { if (ifp->if_flags & IFF_DEBUG) if_printf(ifp, "station %s disassociated" " by peer (reason %d)\n", ether_sprintf(ni->ni_macaddr), reason); ni->ni_associd = 0; - ieee80211_unref_node(&ni); + /* XXX node reclaimed how? */ } break; default: ==== //depot/projects/netperf/sys/net80211/ieee80211_node.c#3 (text+ko) ==== @@ -216,7 +216,6 @@ memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen); ni->ni_rssi = 0; ni->ni_rstamp = 0; - ni->ni_rantenna = 0; memset(ni->ni_tstamp, 0, sizeof(ni->ni_tstamp)); ni->ni_intval = ic->ic_lintval; ni->ni_capinfo = IEEE80211_CAPINFO_IBSS; @@ -289,7 +288,7 @@ } selbs = NULL; if (ifp->if_flags & IFF_DEBUG) - if_printf(ifp, "\tmacaddr bssid chan rssi rate ant flag wep essid\n"); + if_printf(ifp, "\tmacaddr bssid chan rssi rate flag wep essid\n"); for (; ni != NULL; ni = nextbs) { ieee80211_ref_node(ni); nextbs = TAILQ_NEXT(ni, ni_list); @@ -344,7 +343,6 @@ printf(" %+4d", ni->ni_rssi); printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2, fail & 0x08 ? '!' : ' '); - printf(" %3d", ni->ni_rantenna); printf(" %4s%c", (ni->ni_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" : (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" : @@ -497,6 +495,8 @@ static void _ieee80211_free_node(struct ieee80211com *ic, struct ieee80211_node *ni) { + KASSERT(ni != ic->ic_bss, ("freeing bss node")); + TAILQ_REMOVE(&ic->ic_node, ni, ni_list); LIST_REMOVE(ni, ni_hash); if (TAILQ_EMPTY(&ic->ic_node)) ==== //depot/projects/netperf/sys/net80211/ieee80211_node.h#3 (text+ko) ==== @@ -64,9 +64,8 @@ u_int ni_refcnt; /* hardware */ + u_int32_t ni_rstamp; /* recv timestamp */ u_int8_t ni_rssi; /* recv ssi */ - u_int32_t ni_rstamp; /* recv timestamp */ - u_int8_t ni_rantenna; /* recv antenna */ /* header */ u_int8_t ni_macaddr[IEEE80211_ADDR_LEN]; ==== //depot/projects/netperf/sys/net80211/ieee80211_proto.h#2 (text+ko) ==== @@ -55,10 +55,11 @@ extern void ieee80211_proto_attach(struct ifnet *); extern void ieee80211_proto_detach(struct ifnet *); +struct ieee80211_node; extern void ieee80211_input(struct ifnet *, struct mbuf *, - int, u_int32_t, u_int); -extern void ieee80211_recv_mgmt(struct ieee80211com *, struct mbuf *, int, - int, u_int32_t, u_int); + struct ieee80211_node *, int, u_int32_t); +extern void ieee80211_recv_mgmt(struct ieee80211com *, struct mbuf *, + struct ieee80211_node *, int, int, u_int32_t); extern int ieee80211_send_mgmt(struct ieee80211com *, struct ieee80211_node *, int, int); extern int ieee80211_mgmt_output(struct ifnet *, struct ieee80211_node *, ==== //depot/projects/netperf/sys/net80211/ieee80211_var.h#2 (text+ko) ==== @@ -135,7 +135,8 @@ struct ieee80211com { struct arpcom ic_ac; void (*ic_recv_mgmt)(struct ieee80211com *, - struct mbuf *, int, int, u_int32_t, u_int); + struct mbuf *, struct ieee80211_node *, + int, int, u_int32_t); int (*ic_send_mgmt)(struct ieee80211com *, struct ieee80211_node *, int, int); int (*ic_newstate)(struct ieee80211com *,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200308072133.h77LXZbB020498>