PERFORCE change 35734 for review
Sam Leffler
sam at FreeBSD.org
Thu Aug 7 14:33:38 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=35734
Change 35734 by sam at 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 *,
More information about the p4-projects
mailing list