madwifi: fix various noderef/memleak issues
SVN-Revision: 18052
This commit is contained in:
		@@ -853,7 +853,7 @@
 | 
			
		||||
 	}
 | 
			
		||||
 	/* Initialize candidate channels to all available */
 | 
			
		||||
 	memcpy(ic->ic_chan_active, ic->ic_chan_avail,
 | 
			
		||||
@@ -311,11 +296,58 @@ ieee80211_ifattach(struct ieee80211com *
 | 
			
		||||
@@ -311,11 +296,59 @@ ieee80211_ifattach(struct ieee80211com *
 | 
			
		||||
 	 * When 11g is supported, force the rate set to
 | 
			
		||||
 	 * include basic rates suitable for a mixed b/g bss.
 | 
			
		||||
 	 */
 | 
			
		||||
@@ -866,6 +866,7 @@
 | 
			
		||||
+	if (init)
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	ifmedia_removeall(&ic->ic_media);
 | 
			
		||||
+	ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, NULL, NULL);
 | 
			
		||||
+	ieee80211com_media_status(ic->ic_dev, &imr);
 | 
			
		||||
+	ifmedia_set(&ic->ic_media, imr.ifm_active);
 | 
			
		||||
@@ -913,7 +914,7 @@
 | 
			
		||||
 	/* Setup initial channel settings */
 | 
			
		||||
 	ic->ic_bsschan = IEEE80211_CHAN_ANYC;
 | 
			
		||||
 	/* Arbitrarily pick the first channel */
 | 
			
		||||
@@ -327,6 +359,7 @@ ieee80211_ifattach(struct ieee80211com *
 | 
			
		||||
@@ -327,6 +360,7 @@ ieee80211_ifattach(struct ieee80211com *
 | 
			
		||||
 	/* Enable WME by default, if we're capable. */
 | 
			
		||||
 	if (ic->ic_caps & IEEE80211_C_WME)
 | 
			
		||||
 		ic->ic_flags |= IEEE80211_F_WME;
 | 
			
		||||
@@ -921,7 +922,7 @@
 | 
			
		||||
 	(void) ieee80211_setmode(ic, ic->ic_curmode);
 | 
			
		||||
 
 | 
			
		||||
 	/* Store default beacon interval, as nec. */
 | 
			
		||||
@@ -763,7 +796,8 @@ ieee80211_media_setup(struct ieee80211co
 | 
			
		||||
@@ -763,7 +797,8 @@ ieee80211_media_setup(struct ieee80211co
 | 
			
		||||
 	struct ieee80211_rateset allrates;
 | 
			
		||||
 
 | 
			
		||||
 	/* Fill in media characteristics. */
 | 
			
		||||
@@ -931,7 +932,7 @@
 | 
			
		||||
 	maxrate = 0;
 | 
			
		||||
 	memset(&allrates, 0, sizeof(allrates));
 | 
			
		||||
 
 | 
			
		||||
@@ -793,7 +827,7 @@ ieee80211_media_setup(struct ieee80211co
 | 
			
		||||
@@ -793,7 +828,7 @@ ieee80211_media_setup(struct ieee80211co
 | 
			
		||||
 			ADD(media, IFM_AUTO, mopt | IFM_IEEE80211_WDS);
 | 
			
		||||
 		if (mode == IEEE80211_MODE_AUTO)
 | 
			
		||||
 			continue;
 | 
			
		||||
@@ -940,7 +941,7 @@
 | 
			
		||||
 
 | 
			
		||||
 		for (i = 0; i < rs->rs_nrates; i++) {
 | 
			
		||||
 			rate = rs->rs_rates[i];
 | 
			
		||||
@@ -1207,7 +1241,7 @@ ieee80211_announce(struct ieee80211com *
 | 
			
		||||
@@ -1207,7 +1242,7 @@ ieee80211_announce(struct ieee80211com *
 | 
			
		||||
 		if ((ic->ic_modecaps & (1 << mode)) == 0)
 | 
			
		||||
 			continue;
 | 
			
		||||
 		if_printf(dev, "%s rates: ", ieee80211_phymode_name[mode]);
 | 
			
		||||
@@ -949,7 +950,7 @@
 | 
			
		||||
 		for (i = 0; i < rs->rs_nrates; i++) {
 | 
			
		||||
 			rate = rs->rs_rates[i];
 | 
			
		||||
 			mword = ieee80211_rate2media(ic, rate, mode);
 | 
			
		||||
@@ -1417,7 +1451,7 @@ ieee80211com_media_change(struct net_dev
 | 
			
		||||
@@ -1417,7 +1452,7 @@ ieee80211com_media_change(struct net_dev
 | 
			
		||||
 			 * now so drivers have a consistent state.
 | 
			
		||||
 			 */
 | 
			
		||||
 			KASSERT(vap->iv_bss != NULL, ("no bss node"));
 | 
			
		||||
@@ -958,7 +959,7 @@
 | 
			
		||||
 		}
 | 
			
		||||
 		error = -ENETRESET;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -1435,7 +1469,7 @@ findrate(struct ieee80211com *ic, enum i
 | 
			
		||||
@@ -1435,7 +1470,7 @@ findrate(struct ieee80211com *ic, enum i
 | 
			
		||||
 {
 | 
			
		||||
 #define	IEEERATE(_ic,_m,_i) \
 | 
			
		||||
 	((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)
 | 
			
		||||
@@ -967,7 +968,7 @@
 | 
			
		||||
 	for (i = 0; i < nrates; i++)
 | 
			
		||||
 		if (IEEERATE(ic, mode, i) == rate)
 | 
			
		||||
 			return i;
 | 
			
		||||
@@ -1877,11 +1911,6 @@ ieee80211_build_countryie(struct ieee802
 | 
			
		||||
@@ -1877,11 +1912,6 @@ ieee80211_build_countryie(struct ieee802
 | 
			
		||||
 			if (ieee80211_chan2mode(c) != curmode_noturbo)
 | 
			
		||||
 				continue;
 | 
			
		||||
 
 | 
			
		||||
@@ -979,7 +980,7 @@
 | 
			
		||||
 			if (*cur_runlen == 0) {
 | 
			
		||||
 				(*cur_runlen)++;
 | 
			
		||||
 				*cur_pow = c->ic_maxregpower;
 | 
			
		||||
@@ -1915,7 +1944,7 @@ void
 | 
			
		||||
@@ -1915,7 +1945,7 @@ void
 | 
			
		||||
 ieee80211_build_sc_ie(struct ieee80211com *ic)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ieee80211_ie_sc *ie = &ic->ic_sc_ie;
 | 
			
		||||
 
 | 
			
		||||
@@ -1002,7 +1002,7 @@
 | 
			
		||||
 #define skb_tail_pointer(_skb) ((_skb)->tail)
 | 
			
		||||
--- a/net80211/ieee80211.c
 | 
			
		||||
+++ b/net80211/ieee80211.c
 | 
			
		||||
@@ -457,7 +457,7 @@ ieee80211_vap_setup(struct ieee80211com 
 | 
			
		||||
@@ -458,7 +458,7 @@ ieee80211_vap_setup(struct ieee80211com 
 | 
			
		||||
 #define	IEEE80211_C_OPMODE \
 | 
			
		||||
 	(IEEE80211_C_IBSS | IEEE80211_C_HOSTAP | IEEE80211_C_AHDEMO | \
 | 
			
		||||
 	 IEEE80211_C_MONITOR)
 | 
			
		||||
@@ -1011,7 +1011,7 @@
 | 
			
		||||
 	struct net_device *parent = ic->ic_dev;
 | 
			
		||||
 	int err;
 | 
			
		||||
 
 | 
			
		||||
@@ -1354,7 +1354,7 @@ media_status(enum ieee80211_opmode opmod
 | 
			
		||||
@@ -1355,7 +1355,7 @@ media_status(enum ieee80211_opmode opmod
 | 
			
		||||
 static void
 | 
			
		||||
 ieee80211com_media_status(struct net_device *dev, struct ifmediareq *imr)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1020,7 +1020,7 @@
 | 
			
		||||
 
 | 
			
		||||
 	imr->ifm_status = IFM_AVALID;
 | 
			
		||||
 	if (!TAILQ_EMPTY(&ic->ic_vaps))
 | 
			
		||||
@@ -1406,7 +1406,7 @@ media2mode(const struct ifmedia_entry *i
 | 
			
		||||
@@ -1407,7 +1407,7 @@ media2mode(const struct ifmedia_entry *i
 | 
			
		||||
 static int
 | 
			
		||||
 ieee80211com_media_change(struct net_device *dev)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1029,7 +1029,7 @@
 | 
			
		||||
 	struct ieee80211vap *vap;
 | 
			
		||||
 	struct ifmedia_entry *ime = ic->ic_media.ifm_cur;
 | 
			
		||||
 	enum ieee80211_phymode newphymode;
 | 
			
		||||
@@ -1510,7 +1510,7 @@ checkrate(struct ieee80211com *ic, enum 
 | 
			
		||||
@@ -1511,7 +1511,7 @@ checkrate(struct ieee80211com *ic, enum 
 | 
			
		||||
 int
 | 
			
		||||
 ieee80211_media_change(struct net_device *dev)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1038,7 +1038,7 @@
 | 
			
		||||
 	struct ieee80211com *ic = vap->iv_ic;
 | 
			
		||||
 	struct ifmedia_entry *ime = vap->iv_media.ifm_cur;
 | 
			
		||||
 	enum ieee80211_phymode newmode;
 | 
			
		||||
@@ -1544,7 +1544,7 @@ EXPORT_SYMBOL(ieee80211_media_change);
 | 
			
		||||
@@ -1545,7 +1545,7 @@ EXPORT_SYMBOL(ieee80211_media_change);
 | 
			
		||||
 void
 | 
			
		||||
 ieee80211_media_status(struct net_device *dev, struct ifmediareq *imr)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1047,7 +1047,7 @@
 | 
			
		||||
 	struct ieee80211com *ic = vap->iv_ic;
 | 
			
		||||
 	enum ieee80211_phymode mode;
 | 
			
		||||
 	struct ieee80211_rateset *rs;
 | 
			
		||||
@@ -1750,7 +1750,7 @@ EXPORT_SYMBOL(ieee80211_media2rate);
 | 
			
		||||
@@ -1751,7 +1751,7 @@ EXPORT_SYMBOL(ieee80211_media2rate);
 | 
			
		||||
 static struct net_device_stats *
 | 
			
		||||
 ieee80211_getstats(struct net_device *dev)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1056,7 +1056,7 @@
 | 
			
		||||
 	struct net_device_stats *stats = &vap->iv_devstats;
 | 
			
		||||
 
 | 
			
		||||
 	/* XXX: Total guess as to what to count where */
 | 
			
		||||
@@ -1789,7 +1789,7 @@ ieee80211_change_mtu(struct net_device *
 | 
			
		||||
@@ -1790,7 +1790,7 @@ ieee80211_change_mtu(struct net_device *
 | 
			
		||||
 static void
 | 
			
		||||
 ieee80211_set_multicast_list(struct net_device *dev)
 | 
			
		||||
 {
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@ http://madwifi-project.org/changeset/4005
 | 
			
		||||
 	case NETDEV_CHANGENAME:
 | 
			
		||||
--- a/net80211/ieee80211.c
 | 
			
		||||
+++ b/net80211/ieee80211.c
 | 
			
		||||
@@ -450,6 +450,18 @@ ieee80211_ifdetach(struct ieee80211com *
 | 
			
		||||
@@ -451,6 +451,18 @@ ieee80211_ifdetach(struct ieee80211com *
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL(ieee80211_ifdetach);
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,7 @@ http://madwifi-project.org/changeset/4005
 | 
			
		||||
 int
 | 
			
		||||
 ieee80211_vap_setup(struct ieee80211com *ic, struct net_device *dev,
 | 
			
		||||
 	const char *name, int opmode, int flags, struct ieee80211vap *master)
 | 
			
		||||
@@ -470,16 +482,21 @@ ieee80211_vap_setup(struct ieee80211com 
 | 
			
		||||
@@ -471,16 +483,21 @@ ieee80211_vap_setup(struct ieee80211com 
 | 
			
		||||
 		} else
 | 
			
		||||
 			strncpy(dev->name, name, sizeof(dev->name));
 | 
			
		||||
 	}
 | 
			
		||||
@@ -110,7 +110,7 @@ http://madwifi-project.org/changeset/4005
 | 
			
		||||
 	dev->tx_queue_len = 0;			/* NB: bypass queuing */
 | 
			
		||||
 	dev->hard_header_len = parent->hard_header_len;
 | 
			
		||||
 	/*
 | 
			
		||||
@@ -1823,7 +1840,11 @@ ieee80211_set_multicast_list(struct net_
 | 
			
		||||
@@ -1824,7 +1841,11 @@ ieee80211_set_multicast_list(struct net_
 | 
			
		||||
 	IEEE80211_UNLOCK_IRQ(ic);
 | 
			
		||||
 
 | 
			
		||||
 	/* XXX: Merge multicast list into parent device */
 | 
			
		||||
 
 | 
			
		||||
@@ -351,7 +351,7 @@
 | 
			
		||||
 #include <linux/module.h>
 | 
			
		||||
 #include <linux/skbuff.h>
 | 
			
		||||
 #include <linux/netdevice.h>
 | 
			
		||||
@@ -2014,3 +2015,65 @@ ieee80211_build_sc_ie(struct ieee80211co
 | 
			
		||||
@@ -2015,3 +2016,65 @@ ieee80211_build_sc_ie(struct ieee80211co
 | 
			
		||||
 int ath_debug_global = 0;
 | 
			
		||||
 EXPORT_SYMBOL(ath_debug_global);
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,41 +1,184 @@
 | 
			
		||||
--- a/net80211/ieee80211_input.c
 | 
			
		||||
+++ b/net80211/ieee80211_input.c
 | 
			
		||||
@@ -322,7 +322,6 @@ ieee80211_input(struct ieee80211vap * va
 | 
			
		||||
@@ -294,10 +294,10 @@ ieee80211_input(struct ieee80211vap * va
 | 
			
		||||
 			break;
 | 
			
		||||
 		case IEEE80211_M_IBSS:
 | 
			
		||||
 		case IEEE80211_M_AHDEMO:
 | 
			
		||||
-			if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid) ||
 | 
			
		||||
+			if ((!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid) ||
 | 
			
		||||
 			    (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr) &&
 | 
			
		||||
-			     !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
 | 
			
		||||
-			     (subtype != IEEE80211_FC0_SUBTYPE_BEACON))) {
 | 
			
		||||
+			     !IEEE80211_IS_MULTICAST(wh->i_addr1))) &&
 | 
			
		||||
+			     (type == IEEE80211_FC0_TYPE_DATA)) {
 | 
			
		||||
 				if (!(vap->iv_dev->flags & IFF_PROMISC)) {
 | 
			
		||||
 					IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
 | 
			
		||||
 						bssid, NULL, "%s", "not to bss");
 | 
			
		||||
@@ -322,22 +322,15 @@ ieee80211_input(struct ieee80211vap * va
 | 
			
		||||
 			}
 | 
			
		||||
 			/* Do not try to find a node reference if the packet really did come from the BSS */
 | 
			
		||||
 			if (type == IEEE80211_FC0_TYPE_DATA && ni == vap->iv_bss &&
 | 
			
		||||
-					!IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2) &&
 | 
			
		||||
 					IEEE80211_ADDR_EQ(vap->iv_bssid, wh->i_addr3)) {
 | 
			
		||||
 				/* Try to find sender in local node table. */
 | 
			
		||||
 				ni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
 | 
			
		||||
@@ -3572,10 +3571,12 @@ ieee80211_recv_mgmt(struct ieee80211vap 
 | 
			
		||||
-				ni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
 | 
			
		||||
+				if (!ni_or_null) {
 | 
			
		||||
+					ieee80211_unref_node(&ni);
 | 
			
		||||
+					ni = ieee80211_find_txnode(vap, wh->i_addr2);
 | 
			
		||||
+				}
 | 
			
		||||
 				if (ni == NULL) {
 | 
			
		||||
-					/*
 | 
			
		||||
-					 * Fake up a node for this newly discovered
 | 
			
		||||
-					 * member of the IBSS.  This should probably
 | 
			
		||||
-					 * done after an ACL check.
 | 
			
		||||
-					 */
 | 
			
		||||
-					ni = ieee80211_fakeup_adhoc_node(vap,
 | 
			
		||||
-							wh->i_addr2);
 | 
			
		||||
-					if (ni == NULL) {
 | 
			
		||||
-						/* NB: stat kept for alloc failure */
 | 
			
		||||
-						goto err;
 | 
			
		||||
-					}
 | 
			
		||||
+					/* NB: stat kept for alloc failure */
 | 
			
		||||
+					goto discard;
 | 
			
		||||
 				}
 | 
			
		||||
 			}
 | 
			
		||||
 			iwspy_event(vap, ni, rssi);
 | 
			
		||||
@@ -3553,8 +3546,8 @@ ieee80211_recv_mgmt(struct ieee80211vap 
 | 
			
		||||
 				(((vap->iv_opmode == IEEE80211_M_HOSTAP) ||
 | 
			
		||||
 				 (vap->iv_opmode == IEEE80211_M_WDS)) &&
 | 
			
		||||
 				(scan.capinfo & IEEE80211_CAPINFO_ESS))) {
 | 
			
		||||
+			struct ieee80211_node *tni = NULL;
 | 
			
		||||
 			struct ieee80211vap *avp = NULL;
 | 
			
		||||
-			int do_unref = 0;
 | 
			
		||||
 			int found = 0;
 | 
			
		||||
 
 | 
			
		||||
 			IEEE80211_LOCK_IRQ(vap->iv_ic);
 | 
			
		||||
@@ -3568,14 +3561,12 @@ ieee80211_recv_mgmt(struct ieee80211vap 
 | 
			
		||||
 					}
 | 
			
		||||
 				}
 | 
			
		||||
 				if (found)
 | 
			
		||||
-					ni = ni_or_null = avp->iv_wdsnode;
 | 
			
		||||
+					tni = ieee80211_ref_node(avp->iv_wdsnode);
 | 
			
		||||
 			} else if (vap->iv_opmode == IEEE80211_M_WDS) {
 | 
			
		||||
 				found = 1;
 | 
			
		||||
 				ni = ni_or_null = vap->iv_wdsnode;
 | 
			
		||||
-				ni = ni_or_null = vap->iv_wdsnode;
 | 
			
		||||
-			} else if (vap->iv_opmode == IEEE80211_M_IBSS) {
 | 
			
		||||
+			} else if ((vap->iv_opmode == IEEE80211_M_IBSS) && (vap->iv_state == IEEE80211_S_RUN)) {
 | 
			
		||||
 				ni_or_null = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
 | 
			
		||||
-				ni_or_null = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
 | 
			
		||||
-				if (ni_or_null)
 | 
			
		||||
+				if (ni_or_null) {
 | 
			
		||||
 					ni = ni_or_null;
 | 
			
		||||
+					do_unref = 1;
 | 
			
		||||
+				}
 | 
			
		||||
-					ni = ni_or_null;
 | 
			
		||||
+				tni = ieee80211_ref_node(vap->iv_wdsnode);
 | 
			
		||||
+			} else if ((vap->iv_opmode == IEEE80211_M_IBSS) && (vap->iv_state == IEEE80211_S_RUN)) {
 | 
			
		||||
+				tni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
 | 
			
		||||
 				found = 1;
 | 
			
		||||
 			}
 | 
			
		||||
 			IEEE80211_UNLOCK_IRQ(vap->iv_ic);
 | 
			
		||||
@@ -3583,20 +3574,21 @@ ieee80211_recv_mgmt(struct ieee80211vap 
 | 
			
		||||
 			if (!found)
 | 
			
		||||
 				break;
 | 
			
		||||
 
 | 
			
		||||
-			if (ni_or_null == NULL) {
 | 
			
		||||
+			memcpy(&SKB_CB(skb)->beacon_tsf, scan.tstamp, sizeof(u_int64_t));
 | 
			
		||||
+
 | 
			
		||||
+			if (tni == NULL) {
 | 
			
		||||
 				if (avp) {
 | 
			
		||||
 					IEEE80211_LOCK_IRQ(ic);
 | 
			
		||||
-					ni = ieee80211_add_neighbor(avp, wh, &scan);
 | 
			
		||||
+					tni = ieee80211_add_neighbor(avp, wh, &scan);
 | 
			
		||||
 					/* force assoc */
 | 
			
		||||
-					ni->ni_associd |= 0xc000;
 | 
			
		||||
-					avp->iv_wdsnode = ieee80211_ref_node(ni);
 | 
			
		||||
+					tni->ni_associd |= 0xc000;
 | 
			
		||||
+					avp->iv_wdsnode = ieee80211_ref_node(tni);
 | 
			
		||||
 					IEEE80211_UNLOCK_IRQ(ic);
 | 
			
		||||
 				} else if ((vap->iv_opmode == IEEE80211_M_IBSS) &&
 | 
			
		||||
 				           IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid)) {
 | 
			
		||||
 					/* Create a new entry in the neighbor table. */
 | 
			
		||||
-					ni = ieee80211_add_neighbor(vap, wh, &scan);
 | 
			
		||||
+					tni = ieee80211_add_neighbor(vap, wh, &scan);
 | 
			
		||||
 				}
 | 
			
		||||
-				do_unref = 1;
 | 
			
		||||
 			} else {
 | 
			
		||||
 				/*
 | 
			
		||||
 				 * Copy data from beacon to neighbor table.
 | 
			
		||||
@@ -3604,39 +3596,38 @@ ieee80211_recv_mgmt(struct ieee80211vap 
 | 
			
		||||
 				 * ieee80211_add_neighbor(), so we just copy
 | 
			
		||||
 				 * everything over to be safe.
 | 
			
		||||
 				 */
 | 
			
		||||
-				ni->ni_esslen = scan.ssid[1];
 | 
			
		||||
-				memcpy(ni->ni_essid, scan.ssid + 2, scan.ssid[1]);
 | 
			
		||||
-				IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
 | 
			
		||||
-				memcpy(ni->ni_tstamp.data, scan.tstamp,
 | 
			
		||||
-					sizeof(ni->ni_tstamp));
 | 
			
		||||
-				ni->ni_inact = ni->ni_inact_reload;
 | 
			
		||||
-				ni->ni_intval = 
 | 
			
		||||
+				tni->ni_esslen = scan.ssid[1];
 | 
			
		||||
+				memcpy(tni->ni_essid, scan.ssid + 2, scan.ssid[1]);
 | 
			
		||||
+				IEEE80211_ADDR_COPY(tni->ni_bssid, wh->i_addr3);
 | 
			
		||||
+				memcpy(tni->ni_tstamp.data, scan.tstamp,
 | 
			
		||||
+					sizeof(tni->ni_tstamp));
 | 
			
		||||
+				tni->ni_inact = tni->ni_inact_reload;
 | 
			
		||||
+				tni->ni_intval =
 | 
			
		||||
 					IEEE80211_BINTVAL_SANITISE(scan.bintval);
 | 
			
		||||
-				ni->ni_capinfo = scan.capinfo;
 | 
			
		||||
-				ni->ni_chan = ic->ic_curchan;
 | 
			
		||||
-				ni->ni_fhdwell = scan.fhdwell;
 | 
			
		||||
-				ni->ni_fhindex = scan.fhindex;
 | 
			
		||||
-				ni->ni_erp = scan.erp;
 | 
			
		||||
-				ni->ni_timoff = scan.timoff;
 | 
			
		||||
+				tni->ni_capinfo = scan.capinfo;
 | 
			
		||||
+				tni->ni_chan = ic->ic_curchan;
 | 
			
		||||
+				tni->ni_fhdwell = scan.fhdwell;
 | 
			
		||||
+				tni->ni_fhindex = scan.fhindex;
 | 
			
		||||
+				tni->ni_erp = scan.erp;
 | 
			
		||||
+				tni->ni_timoff = scan.timoff;
 | 
			
		||||
 				if (scan.wme != NULL)
 | 
			
		||||
-					ieee80211_saveie(&ni->ni_wme_ie, scan.wme);
 | 
			
		||||
+					ieee80211_saveie(&tni->ni_wme_ie, scan.wme);
 | 
			
		||||
 				if (scan.wpa != NULL)
 | 
			
		||||
-					ieee80211_saveie(&ni->ni_wpa_ie, scan.wpa);
 | 
			
		||||
+					ieee80211_saveie(&tni->ni_wpa_ie, scan.wpa);
 | 
			
		||||
 				if (scan.rsn != NULL)
 | 
			
		||||
-					ieee80211_saveie(&ni->ni_rsn_ie, scan.rsn);
 | 
			
		||||
+					ieee80211_saveie(&tni->ni_rsn_ie, scan.rsn);
 | 
			
		||||
 				if (scan.ath != NULL)
 | 
			
		||||
-					ieee80211_saveath(ni, scan.ath);
 | 
			
		||||
+					ieee80211_saveath(tni, scan.ath);
 | 
			
		||||
 
 | 
			
		||||
 				/* NB: must be after ni_chan is setup */
 | 
			
		||||
-				ieee80211_setup_rates(ni, scan.rates,
 | 
			
		||||
+				ieee80211_setup_rates(tni, scan.rates,
 | 
			
		||||
 					scan.xrates, IEEE80211_F_DOSORT);
 | 
			
		||||
 			}
 | 
			
		||||
-			if (ni != NULL) {
 | 
			
		||||
-				ni->ni_rssi = rssi;
 | 
			
		||||
-				ni->ni_rtsf = rtsf;
 | 
			
		||||
-				ni->ni_last_rx = jiffies;
 | 
			
		||||
-				if (do_unref)
 | 
			
		||||
-					ieee80211_unref_node(&ni);
 | 
			
		||||
+			if (tni != NULL) {
 | 
			
		||||
+				tni->ni_rssi = rssi;
 | 
			
		||||
+				tni->ni_rtsf = rtsf;
 | 
			
		||||
+				tni->ni_last_rx = jiffies;
 | 
			
		||||
+				ieee80211_unref_node(&tni);
 | 
			
		||||
 			}
 | 
			
		||||
 		}
 | 
			
		||||
 		break;
 | 
			
		||||
--- a/net80211/ieee80211_node.c
 | 
			
		||||
+++ b/net80211/ieee80211_node.c
 | 
			
		||||
@@ -317,16 +317,16 @@ ieee80211_create_ibss(struct ieee80211va
 | 
			
		||||
@@ -53,6 +53,7 @@
 | 
			
		||||
 
 | 
			
		||||
 #include <net80211/ieee80211_var.h>
 | 
			
		||||
 #include <net80211/if_athproto.h>
 | 
			
		||||
+#include <net80211/ieee80211_node.h>
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * Association IDs are managed with a bit vector.
 | 
			
		||||
@@ -317,16 +318,11 @@ ieee80211_create_ibss(struct ieee80211va
 | 
			
		||||
 	/* Check to see if we already have a node for this mac
 | 
			
		||||
 	 * NB: we gain a node reference here
 | 
			
		||||
 	 */
 | 
			
		||||
-	ni = ieee80211_find_txnode(vap, vap->iv_myaddr);
 | 
			
		||||
+	ni = ieee80211_find_node(&ic->ic_sta, vap->iv_myaddr);
 | 
			
		||||
+	if (ni) {
 | 
			
		||||
+		ieee80211_node_leave(ni);
 | 
			
		||||
+		ieee80211_unref_node(&ni);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	ieee80211_node_table_reset(&ic->ic_sta, vap);
 | 
			
		||||
+	ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr);
 | 
			
		||||
 	if (ni == NULL) {
 | 
			
		||||
-		ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr);
 | 
			
		||||
@@ -51,23 +194,50 @@
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_myaddr);
 | 
			
		||||
@@ -759,6 +759,9 @@ ieee80211_sta_join(struct ieee80211vap *
 | 
			
		||||
 	ieee80211_setup_rates(ni, se->se_rates, se->se_xrates,
 | 
			
		||||
 		IEEE80211_F_DOSORT | IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
 | 
			
		||||
@@ -429,8 +425,8 @@ ieee80211_reset_bss(struct ieee80211vap 
 | 
			
		||||
 			  __func__, ni, MAC_ADDR(vap->iv_myaddr));
 | 
			
		||||
 	KASSERT(ni != NULL, ("unable to setup inital BSS node"));
 | 
			
		||||
 
 | 
			
		||||
+	if (vap->iv_opmode == IEEE80211_M_IBSS)
 | 
			
		||||
+		ieee80211_node_table_reset(&vap->iv_ic->ic_sta, vap);
 | 
			
		||||
+
 | 
			
		||||
 	return ieee80211_sta_join1(PASS_NODE(ni));
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL(ieee80211_sta_join);
 | 
			
		||||
-	vap->iv_bss = ieee80211_ref_node(ni);
 | 
			
		||||
-	KASSERT((atomic_read(&vap->iv_bss->ni_refcnt) == 3), 
 | 
			
		||||
+	vap->iv_bss = ni;
 | 
			
		||||
+	KASSERT((atomic_read(&vap->iv_bss->ni_refcnt) == 2),
 | 
			
		||||
 		("wrong refcount for new node."));
 | 
			
		||||
 
 | 
			
		||||
 	if (obss != NULL) {
 | 
			
		||||
@@ -647,7 +643,7 @@ ieee80211_sta_join1(struct ieee80211_nod
 | 
			
		||||
 		(vap->iv_state == IEEE80211_S_RUN) && bssid_equal(obss, selbs)); */
 | 
			
		||||
 	vap->iv_bss = selbs;
 | 
			
		||||
 	IEEE80211_ADDR_COPY(vap->iv_bssid, selbs->ni_bssid);
 | 
			
		||||
-	if (obss != NULL) {
 | 
			
		||||
+	if ((obss != NULL) && (obss != selbs)) {
 | 
			
		||||
 		if (obss->ni_table)
 | 
			
		||||
 			ieee80211_node_leave(obss);
 | 
			
		||||
 		ieee80211_unref_node(&obss);
 | 
			
		||||
--- a/ath/if_ath.c
 | 
			
		||||
+++ b/ath/if_ath.c
 | 
			
		||||
@@ -6655,10 +6655,8 @@ ath_recv_mgmt(struct ieee80211vap * vap,
 | 
			
		||||
@@ -6625,14 +6625,6 @@ ath_recv_mgmt(struct ieee80211vap * vap,
 | 
			
		||||
 
 | 
			
		||||
 	sc->sc_recv_mgmt(vap, ni_or_null, skb, subtype, rssi, rtsf);
 | 
			
		||||
 
 | 
			
		||||
-	/* Lookup the new node if any (this grabs a reference to it) */
 | 
			
		||||
-	ni = ieee80211_find_rxnode(vap->iv_ic, vap,
 | 
			
		||||
-	         (const struct ieee80211_frame_min *)skb->data);
 | 
			
		||||
-	if (ni == NULL) {
 | 
			
		||||
-		DPRINTF(sc, ATH_DEBUG_BEACON, "Dropping; node unknown.\n");
 | 
			
		||||
-		return;
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
 	switch (subtype) {
 | 
			
		||||
 	case IEEE80211_FC0_SUBTYPE_BEACON:
 | 
			
		||||
 		/* update RSSI statistics for use by the HAL */
 | 
			
		||||
@@ -6654,11 +6646,9 @@ ath_recv_mgmt(struct ieee80211vap * vap,
 | 
			
		||||
 			 * we do the IBSS merging in software. Also do not merge
 | 
			
		||||
 			 * if the difference it too small. Otherwise we are playing
 | 
			
		||||
 			 * tsf-pingpong with other vendors drivers */
 | 
			
		||||
 			beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf);
 | 
			
		||||
-			beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf);
 | 
			
		||||
-			if (beacon_tsf > rtsf + 0xffff) {
 | 
			
		||||
+			beacon_tsf = le64_to_cpu(SKB_CB(skb)->beacon_tsf);
 | 
			
		||||
+			if (beacon_tsf > rtsf + 0xffff)
 | 
			
		||||
 				ath_hal_settsf64(sc->sc_ah, beacon_tsf - rtsf);
 | 
			
		||||
-				ieee80211_ibss_merge(ni);
 | 
			
		||||
@@ -75,3 +245,109 @@
 | 
			
		||||
 			break;
 | 
			
		||||
 		}
 | 
			
		||||
 		/* NB: Fall Through */
 | 
			
		||||
@@ -6680,13 +6670,21 @@ ath_recv_mgmt(struct ieee80211vap * vap,
 | 
			
		||||
 			hw_tsf = ath_hal_gettsf64(sc->sc_ah);
 | 
			
		||||
 			hw_tu  = hw_tsf >> 10;
 | 
			
		||||
 
 | 
			
		||||
-			beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf);
 | 
			
		||||
+			beacon_tsf = le64_to_cpu(SKB_CB(skb)->beacon_tsf);
 | 
			
		||||
 			beacon_tu  = beacon_tsf >> 10;
 | 
			
		||||
 
 | 
			
		||||
+			if (!beacon_tsf)
 | 
			
		||||
+				break;
 | 
			
		||||
+
 | 
			
		||||
+			if (IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid))
 | 
			
		||||
+				break;
 | 
			
		||||
+
 | 
			
		||||
 			DPRINTF(sc, ATH_DEBUG_BEACON,
 | 
			
		||||
-					"Beacon transmitted at %10llx, "
 | 
			
		||||
+					"Beacon transmitted from "MAC_FMT" ("MAC_FMT") at %10llx, "
 | 
			
		||||
 					"received at %10llx(%lld), hw TSF "
 | 
			
		||||
 					"%10llx(%lld)\n",
 | 
			
		||||
+					MAC_ADDR(wh->i_addr3),
 | 
			
		||||
+					MAC_ADDR(vap->iv_bssid),
 | 
			
		||||
 					beacon_tsf,
 | 
			
		||||
 					rtsf, rtsf - beacon_tsf,
 | 
			
		||||
 					hw_tsf, hw_tsf - beacon_tsf);
 | 
			
		||||
@@ -6699,39 +6697,13 @@ ath_recv_mgmt(struct ieee80211vap * vap,
 | 
			
		||||
 				do_merge = 1;
 | 
			
		||||
 			}
 | 
			
		||||
 
 | 
			
		||||
-			/* Check sc_nexttbtt */
 | 
			
		||||
-			if (sc->sc_nexttbtt < hw_tu) {
 | 
			
		||||
-				DPRINTF(sc, ATH_DEBUG_BEACON,
 | 
			
		||||
-					"sc_nexttbtt (%8x TU) is in the past "
 | 
			
		||||
-					"(tsf %8x TU), updating timers\n",
 | 
			
		||||
-					sc->sc_nexttbtt, hw_tu);
 | 
			
		||||
-				do_merge = 1;
 | 
			
		||||
-			}
 | 
			
		||||
-
 | 
			
		||||
-			intval = ni->ni_intval & HAL_BEACON_PERIOD;
 | 
			
		||||
-#if 0
 | 
			
		||||
-			/* This code is disabled since it would produce
 | 
			
		||||
-			 * unwanted merge. For instance, in a two nodes network
 | 
			
		||||
-			 * A & B, A can merge to B and at the same time, B will
 | 
			
		||||
-			 * merge to A, still having a split */
 | 
			
		||||
-			if (intval != 0) {
 | 
			
		||||
-				if ((sc->sc_nexttbtt % intval) !=
 | 
			
		||||
-						(beacon_tu % intval)) {
 | 
			
		||||
-					DPRINTF(sc, ATH_DEBUG_BEACON,
 | 
			
		||||
-							"ibss merge: "
 | 
			
		||||
-							"sc_nexttbtt %10x TU "
 | 
			
		||||
-							"(%3d) beacon %10x TU "
 | 
			
		||||
-							"(%3d)\n",
 | 
			
		||||
-							sc->sc_nexttbtt,
 | 
			
		||||
-							sc->sc_nexttbtt % intval,
 | 
			
		||||
-							beacon_tu,
 | 
			
		||||
-							beacon_tu % intval);
 | 
			
		||||
-					do_merge = 1;
 | 
			
		||||
-				}
 | 
			
		||||
-			}
 | 
			
		||||
-#endif
 | 
			
		||||
-			if (do_merge)
 | 
			
		||||
+			if (do_merge) {
 | 
			
		||||
+				/* Lookup the new node if any (this grabs a reference to it) */
 | 
			
		||||
+				ni = ieee80211_find_txnode(vap, wh->i_addr2);
 | 
			
		||||
+				memcpy(ni->ni_bssid, wh->i_addr3, IEEE80211_ADDR_LEN);
 | 
			
		||||
 				ieee80211_ibss_merge(ni);
 | 
			
		||||
+				ieee80211_unref_node(&ni);
 | 
			
		||||
+			}
 | 
			
		||||
 
 | 
			
		||||
 			if ((sc->sc_opmode == HAL_M_IBSS) &&
 | 
			
		||||
 					ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval))
 | 
			
		||||
@@ -6739,8 +6711,6 @@ ath_recv_mgmt(struct ieee80211vap * vap,
 | 
			
		||||
 		}
 | 
			
		||||
 		break;
 | 
			
		||||
 	}
 | 
			
		||||
-
 | 
			
		||||
-	ieee80211_unref_node(&ni);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void
 | 
			
		||||
--- a/net80211/ieee80211_linux.h
 | 
			
		||||
+++ b/net80211/ieee80211_linux.h
 | 
			
		||||
@@ -411,7 +411,7 @@ typedef spinlock_t acl_lock_t;
 | 
			
		||||
  *     8 bytes so we reserve/avoid it.
 | 
			
		||||
  */
 | 
			
		||||
 	struct ieee80211_cb {
 | 
			
		||||
-	u_int8_t vlan[8];			/* reserve for vlan tag info */
 | 
			
		||||
+	u_int64_t beacon_tsf;
 | 
			
		||||
 	struct ieee80211_node *ni;
 | 
			
		||||
 	u_int32_t flags;
 | 
			
		||||
 #define	M_LINK0		0x01			/* frame needs WEP encryption */
 | 
			
		||||
--- a/net80211/ieee80211_scan_sta.c
 | 
			
		||||
+++ b/net80211/ieee80211_scan_sta.c
 | 
			
		||||
@@ -1125,11 +1125,8 @@ adhoc_default_action(struct ieee80211vap
 | 
			
		||||
 	u_int8_t zeroMacAddr[IEEE80211_ADDR_LEN];
 | 
			
		||||
 
 | 
			
		||||
 	memset(&zeroMacAddr, 0, IEEE80211_ADDR_LEN);
 | 
			
		||||
-	if (IEEE80211_ADDR_EQ(se->se_bssid, &zeroMacAddr[0])) {
 | 
			
		||||
-		ieee80211_create_ibss(vap, se->se_chan);
 | 
			
		||||
-		return 1;
 | 
			
		||||
-	} else
 | 
			
		||||
-		return ieee80211_sta_join(vap, se);
 | 
			
		||||
+	ieee80211_create_ibss(vap, se->se_chan);
 | 
			
		||||
+	return 1;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct ieee80211_scanner adhoc_default = {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user