Skip site navigation (1)Skip section navigation (2)
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>