451-ibss_race_fix.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. --- a/net80211/ieee80211_input.c
  2. +++ b/net80211/ieee80211_input.c
  3. @@ -294,10 +294,10 @@ ieee80211_input(struct ieee80211vap * va
  4. break;
  5. case IEEE80211_M_IBSS:
  6. case IEEE80211_M_AHDEMO:
  7. - if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid) ||
  8. + if ((!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid) ||
  9. (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr) &&
  10. - !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
  11. - (subtype != IEEE80211_FC0_SUBTYPE_BEACON))) {
  12. + !IEEE80211_IS_MULTICAST(wh->i_addr1))) &&
  13. + (type == IEEE80211_FC0_TYPE_DATA)) {
  14. if (!(vap->iv_dev->flags & IFF_PROMISC)) {
  15. IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
  16. bssid, NULL, "%s", "not to bss");
  17. @@ -322,22 +322,15 @@ ieee80211_input(struct ieee80211vap * va
  18. }
  19. /* Do not try to find a node reference if the packet really did come from the BSS */
  20. if (type == IEEE80211_FC0_TYPE_DATA && ni == vap->iv_bss &&
  21. - !IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2) &&
  22. IEEE80211_ADDR_EQ(vap->iv_bssid, wh->i_addr3)) {
  23. /* Try to find sender in local node table. */
  24. - ni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
  25. + if (!ni_or_null) {
  26. + ieee80211_unref_node(&ni);
  27. + ni = ieee80211_find_txnode(vap, wh->i_addr2);
  28. + }
  29. if (ni == NULL) {
  30. - /*
  31. - * Fake up a node for this newly discovered
  32. - * member of the IBSS. This should probably
  33. - * done after an ACL check.
  34. - */
  35. - ni = ieee80211_fakeup_adhoc_node(vap,
  36. - wh->i_addr2);
  37. - if (ni == NULL) {
  38. - /* NB: stat kept for alloc failure */
  39. - goto err;
  40. - }
  41. + /* NB: stat kept for alloc failure */
  42. + goto discard;
  43. }
  44. }
  45. iwspy_event(vap, ni, rssi);
  46. @@ -3553,8 +3546,8 @@ ieee80211_recv_mgmt(struct ieee80211vap
  47. (((vap->iv_opmode == IEEE80211_M_HOSTAP) ||
  48. (vap->iv_opmode == IEEE80211_M_WDS)) &&
  49. (scan.capinfo & IEEE80211_CAPINFO_ESS))) {
  50. + struct ieee80211_node *tni = NULL;
  51. struct ieee80211vap *avp = NULL;
  52. - int do_unref = 0;
  53. int found = 0;
  54. IEEE80211_LOCK_IRQ(vap->iv_ic);
  55. @@ -3568,14 +3561,12 @@ ieee80211_recv_mgmt(struct ieee80211vap
  56. }
  57. }
  58. if (found)
  59. - ni = ni_or_null = avp->iv_wdsnode;
  60. + tni = ieee80211_ref_node(avp->iv_wdsnode);
  61. } else if (vap->iv_opmode == IEEE80211_M_WDS) {
  62. found = 1;
  63. - ni = ni_or_null = vap->iv_wdsnode;
  64. - } else if (vap->iv_opmode == IEEE80211_M_IBSS) {
  65. - ni_or_null = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
  66. - if (ni_or_null)
  67. - ni = ni_or_null;
  68. + tni = ieee80211_ref_node(vap->iv_wdsnode);
  69. + } else if ((vap->iv_opmode == IEEE80211_M_IBSS) && (vap->iv_state == IEEE80211_S_RUN)) {
  70. + tni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
  71. found = 1;
  72. }
  73. IEEE80211_UNLOCK_IRQ(vap->iv_ic);
  74. @@ -3583,20 +3574,21 @@ ieee80211_recv_mgmt(struct ieee80211vap
  75. if (!found)
  76. break;
  77. - if (ni_or_null == NULL) {
  78. + memcpy(&SKB_CB(skb)->beacon_tsf, scan.tstamp, sizeof(u_int64_t));
  79. +
  80. + if (tni == NULL) {
  81. if (avp) {
  82. IEEE80211_LOCK_IRQ(ic);
  83. - ni = ieee80211_add_neighbor(avp, wh, &scan);
  84. + tni = ieee80211_add_neighbor(avp, wh, &scan);
  85. /* force assoc */
  86. - ni->ni_associd |= 0xc000;
  87. - avp->iv_wdsnode = ieee80211_ref_node(ni);
  88. + tni->ni_associd |= 0xc000;
  89. + avp->iv_wdsnode = ieee80211_ref_node(tni);
  90. IEEE80211_UNLOCK_IRQ(ic);
  91. } else if ((vap->iv_opmode == IEEE80211_M_IBSS) &&
  92. IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid)) {
  93. /* Create a new entry in the neighbor table. */
  94. - ni = ieee80211_add_neighbor(vap, wh, &scan);
  95. + tni = ieee80211_add_neighbor(vap, wh, &scan);
  96. }
  97. - do_unref = 1;
  98. } else {
  99. /*
  100. * Copy data from beacon to neighbor table.
  101. @@ -3604,39 +3596,38 @@ ieee80211_recv_mgmt(struct ieee80211vap
  102. * ieee80211_add_neighbor(), so we just copy
  103. * everything over to be safe.
  104. */
  105. - ni->ni_esslen = scan.ssid[1];
  106. - memcpy(ni->ni_essid, scan.ssid + 2, scan.ssid[1]);
  107. - IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
  108. - memcpy(ni->ni_tstamp.data, scan.tstamp,
  109. - sizeof(ni->ni_tstamp));
  110. - ni->ni_inact = ni->ni_inact_reload;
  111. - ni->ni_intval =
  112. + tni->ni_esslen = scan.ssid[1];
  113. + memcpy(tni->ni_essid, scan.ssid + 2, scan.ssid[1]);
  114. + IEEE80211_ADDR_COPY(tni->ni_bssid, wh->i_addr3);
  115. + memcpy(tni->ni_tstamp.data, scan.tstamp,
  116. + sizeof(tni->ni_tstamp));
  117. + tni->ni_inact = tni->ni_inact_reload;
  118. + tni->ni_intval =
  119. IEEE80211_BINTVAL_SANITISE(scan.bintval);
  120. - ni->ni_capinfo = scan.capinfo;
  121. - ni->ni_chan = ic->ic_curchan;
  122. - ni->ni_fhdwell = scan.fhdwell;
  123. - ni->ni_fhindex = scan.fhindex;
  124. - ni->ni_erp = scan.erp;
  125. - ni->ni_timoff = scan.timoff;
  126. + tni->ni_capinfo = scan.capinfo;
  127. + tni->ni_chan = ic->ic_curchan;
  128. + tni->ni_fhdwell = scan.fhdwell;
  129. + tni->ni_fhindex = scan.fhindex;
  130. + tni->ni_erp = scan.erp;
  131. + tni->ni_timoff = scan.timoff;
  132. if (scan.wme != NULL)
  133. - ieee80211_saveie(&ni->ni_wme_ie, scan.wme);
  134. + ieee80211_saveie(&tni->ni_wme_ie, scan.wme);
  135. if (scan.wpa != NULL)
  136. - ieee80211_saveie(&ni->ni_wpa_ie, scan.wpa);
  137. + ieee80211_saveie(&tni->ni_wpa_ie, scan.wpa);
  138. if (scan.rsn != NULL)
  139. - ieee80211_saveie(&ni->ni_rsn_ie, scan.rsn);
  140. + ieee80211_saveie(&tni->ni_rsn_ie, scan.rsn);
  141. if (scan.ath != NULL)
  142. - ieee80211_saveath(ni, scan.ath);
  143. + ieee80211_saveath(tni, scan.ath);
  144. /* NB: must be after ni_chan is setup */
  145. - ieee80211_setup_rates(ni, scan.rates,
  146. + ieee80211_setup_rates(tni, scan.rates,
  147. scan.xrates, IEEE80211_F_DOSORT);
  148. }
  149. - if (ni != NULL) {
  150. - ni->ni_rssi = rssi;
  151. - ni->ni_rtsf = rtsf;
  152. - ni->ni_last_rx = jiffies;
  153. - if (do_unref)
  154. - ieee80211_unref_node(&ni);
  155. + if (tni != NULL) {
  156. + tni->ni_rssi = rssi;
  157. + tni->ni_rtsf = rtsf;
  158. + tni->ni_last_rx = jiffies;
  159. + ieee80211_unref_node(&tni);
  160. }
  161. }
  162. break;
  163. --- a/net80211/ieee80211_node.c
  164. +++ b/net80211/ieee80211_node.c
  165. @@ -53,6 +53,7 @@
  166. #include <net80211/ieee80211_var.h>
  167. #include <net80211/if_athproto.h>
  168. +#include <net80211/ieee80211_node.h>
  169. /*
  170. * Association IDs are managed with a bit vector.
  171. @@ -317,16 +318,11 @@ ieee80211_create_ibss(struct ieee80211va
  172. /* Check to see if we already have a node for this mac
  173. * NB: we gain a node reference here
  174. */
  175. - ni = ieee80211_find_txnode(vap, vap->iv_myaddr);
  176. + ieee80211_node_table_reset(&ic->ic_sta, vap);
  177. + ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr);
  178. if (ni == NULL) {
  179. - ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr);
  180. - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
  181. - "%s: ni:%p allocated for " MAC_FMT "\n",
  182. - __func__, ni, MAC_ADDR(vap->iv_myaddr));
  183. - if (ni == NULL) {
  184. - /* XXX recovery? */
  185. - return;
  186. - }
  187. + /* XXX recovery? */
  188. + return;
  189. }
  190. IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_myaddr);
  191. @@ -647,7 +643,7 @@ ieee80211_sta_join1(struct ieee80211_nod
  192. (vap->iv_state == IEEE80211_S_RUN) && bssid_equal(obss, selbs)); */
  193. vap->iv_bss = selbs;
  194. IEEE80211_ADDR_COPY(vap->iv_bssid, selbs->ni_bssid);
  195. - if (obss != NULL) {
  196. + if ((obss != NULL) && (obss != selbs)) {
  197. if (obss->ni_table)
  198. ieee80211_node_leave(obss);
  199. ieee80211_unref_node(&obss);
  200. --- a/ath/if_ath.c
  201. +++ b/ath/if_ath.c
  202. @@ -6625,14 +6625,6 @@ ath_recv_mgmt(struct ieee80211vap * vap,
  203. sc->sc_recv_mgmt(vap, ni_or_null, skb, subtype, rssi, rtsf);
  204. - /* Lookup the new node if any (this grabs a reference to it) */
  205. - ni = ieee80211_find_rxnode(vap->iv_ic, vap,
  206. - (const struct ieee80211_frame_min *)skb->data);
  207. - if (ni == NULL) {
  208. - DPRINTF(sc, ATH_DEBUG_BEACON, "Dropping; node unknown.\n");
  209. - return;
  210. - }
  211. -
  212. switch (subtype) {
  213. case IEEE80211_FC0_SUBTYPE_BEACON:
  214. /* update RSSI statistics for use by the HAL */
  215. @@ -6654,11 +6646,9 @@ ath_recv_mgmt(struct ieee80211vap * vap,
  216. * we do the IBSS merging in software. Also do not merge
  217. * if the difference it too small. Otherwise we are playing
  218. * tsf-pingpong with other vendors drivers */
  219. - beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf);
  220. - if (beacon_tsf > rtsf + 0xffff) {
  221. + beacon_tsf = le64_to_cpu(SKB_CB(skb)->beacon_tsf);
  222. + if (beacon_tsf > rtsf + 0xffff)
  223. ath_hal_settsf64(sc->sc_ah, beacon_tsf - rtsf);
  224. - ieee80211_ibss_merge(ni);
  225. - }
  226. break;
  227. }
  228. /* NB: Fall Through */
  229. @@ -6680,13 +6670,21 @@ ath_recv_mgmt(struct ieee80211vap * vap,
  230. hw_tsf = ath_hal_gettsf64(sc->sc_ah);
  231. hw_tu = hw_tsf >> 10;
  232. - beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf);
  233. + beacon_tsf = le64_to_cpu(SKB_CB(skb)->beacon_tsf);
  234. beacon_tu = beacon_tsf >> 10;
  235. + if (!beacon_tsf)
  236. + break;
  237. +
  238. + if (IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid))
  239. + break;
  240. +
  241. DPRINTF(sc, ATH_DEBUG_BEACON,
  242. - "Beacon transmitted at %10llx, "
  243. + "Beacon transmitted from "MAC_FMT" ("MAC_FMT") at %10llx, "
  244. "received at %10llx(%lld), hw TSF "
  245. "%10llx(%lld)\n",
  246. + MAC_ADDR(wh->i_addr3),
  247. + MAC_ADDR(vap->iv_bssid),
  248. beacon_tsf,
  249. rtsf, rtsf - beacon_tsf,
  250. hw_tsf, hw_tsf - beacon_tsf);
  251. @@ -6699,39 +6697,13 @@ ath_recv_mgmt(struct ieee80211vap * vap,
  252. do_merge = 1;
  253. }
  254. - /* Check sc_nexttbtt */
  255. - if (sc->sc_nexttbtt < hw_tu) {
  256. - DPRINTF(sc, ATH_DEBUG_BEACON,
  257. - "sc_nexttbtt (%8x TU) is in the past "
  258. - "(tsf %8x TU), updating timers\n",
  259. - sc->sc_nexttbtt, hw_tu);
  260. - do_merge = 1;
  261. - }
  262. -
  263. - intval = ni->ni_intval & HAL_BEACON_PERIOD;
  264. -#if 0
  265. - /* This code is disabled since it would produce
  266. - * unwanted merge. For instance, in a two nodes network
  267. - * A & B, A can merge to B and at the same time, B will
  268. - * merge to A, still having a split */
  269. - if (intval != 0) {
  270. - if ((sc->sc_nexttbtt % intval) !=
  271. - (beacon_tu % intval)) {
  272. - DPRINTF(sc, ATH_DEBUG_BEACON,
  273. - "ibss merge: "
  274. - "sc_nexttbtt %10x TU "
  275. - "(%3d) beacon %10x TU "
  276. - "(%3d)\n",
  277. - sc->sc_nexttbtt,
  278. - sc->sc_nexttbtt % intval,
  279. - beacon_tu,
  280. - beacon_tu % intval);
  281. - do_merge = 1;
  282. - }
  283. - }
  284. -#endif
  285. - if (do_merge)
  286. + if (do_merge) {
  287. + /* Lookup the new node if any (this grabs a reference to it) */
  288. + ni = ieee80211_find_txnode(vap, wh->i_addr2);
  289. + memcpy(ni->ni_bssid, wh->i_addr3, IEEE80211_ADDR_LEN);
  290. ieee80211_ibss_merge(ni);
  291. + ieee80211_unref_node(&ni);
  292. + }
  293. if ((sc->sc_opmode == HAL_M_IBSS) &&
  294. ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval))
  295. @@ -6739,8 +6711,6 @@ ath_recv_mgmt(struct ieee80211vap * vap,
  296. }
  297. break;
  298. }
  299. -
  300. - ieee80211_unref_node(&ni);
  301. }
  302. static void
  303. --- a/net80211/ieee80211_linux.h
  304. +++ b/net80211/ieee80211_linux.h
  305. @@ -411,7 +411,7 @@ typedef spinlock_t acl_lock_t;
  306. * 8 bytes so we reserve/avoid it.
  307. */
  308. struct ieee80211_cb {
  309. - u_int8_t vlan[8]; /* reserve for vlan tag info */
  310. + u_int64_t beacon_tsf;
  311. struct ieee80211_node *ni;
  312. u_int32_t flags;
  313. #define M_LINK0 0x01 /* frame needs WEP encryption */
  314. --- a/net80211/ieee80211_scan_sta.c
  315. +++ b/net80211/ieee80211_scan_sta.c
  316. @@ -1125,11 +1125,8 @@ adhoc_default_action(struct ieee80211vap
  317. u_int8_t zeroMacAddr[IEEE80211_ADDR_LEN];
  318. memset(&zeroMacAddr, 0, IEEE80211_ADDR_LEN);
  319. - if (IEEE80211_ADDR_EQ(se->se_bssid, &zeroMacAddr[0])) {
  320. - ieee80211_create_ibss(vap, se->se_chan);
  321. - return 1;
  322. - } else
  323. - return ieee80211_sta_join(vap, se);
  324. + ieee80211_create_ibss(vap, se->se_chan);
  325. + return 1;
  326. }
  327. static const struct ieee80211_scanner adhoc_default = {