| 1 | --- a/ath/if_ath.c |
| 2 | +++ b/ath/if_ath.c |
| 3 | @@ -6641,10 +6641,8 @@ static void |
| 4 | ath_recv_mgmt(struct ieee80211vap * vap, struct ieee80211_node *ni_or_null, |
| 5 | struct sk_buff *skb, int subtype, int rssi, u_int64_t rtsf) |
| 6 | { |
| 7 | + const struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data; |
| 8 | struct ath_softc *sc = netdev_priv(vap->iv_ic->ic_dev); |
| 9 | -#ifdef AR_DEBUG |
| 10 | - struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data; |
| 11 | -#endif |
| 12 | struct ieee80211_node * ni = ni_or_null; |
| 13 | u_int64_t hw_tsf, beacon_tsf; |
| 14 | u_int32_t hw_tu, beacon_tu, intval; |
| 15 | @@ -6686,7 +6684,7 @@ ath_recv_mgmt(struct ieee80211vap * vap, |
| 16 | } |
| 17 | if ((vap->iv_opmode == IEEE80211_M_IBSS) && |
| 18 | (sc->sc_opmode == HAL_M_HOSTAP) && |
| 19 | - IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) { |
| 20 | + IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid)) { |
| 21 | /* In this mode, we drive the HAL in HOSTAP mode. Hence |
| 22 | * we do the IBSS merging in software. Also do not merge |
| 23 | * if the difference it too small. Otherwise we are playing |
| 24 | --- a/net80211/ieee80211_input.c |
| 25 | +++ b/net80211/ieee80211_input.c |
| 26 | @@ -311,7 +311,8 @@ ieee80211_input(struct ieee80211vap * va |
| 27 | } |
| 28 | /* Do not try to find a node reference if the packet really did come from the BSS */ |
| 29 | if (type == IEEE80211_FC0_TYPE_DATA && ni == vap->iv_bss && |
| 30 | - !IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2)) { |
| 31 | + !IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2) && |
| 32 | + IEEE80211_ADDR_EQ(vap->iv_bssid, wh->i_addr3)) { |
| 33 | /* Try to find sender in local node table. */ |
| 34 | ni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2); |
| 35 | if (ni == NULL) { |
| 36 | @@ -513,6 +514,10 @@ ieee80211_input(struct ieee80211vap * va |
| 37 | break; |
| 38 | case IEEE80211_M_IBSS: |
| 39 | case IEEE80211_M_AHDEMO: |
| 40 | + /* ignore foreign data frames */ |
| 41 | + if (ni == vap->iv_bss) |
| 42 | + goto out; |
| 43 | + |
| 44 | if (dir != IEEE80211_FC1_DIR_NODS) { |
| 45 | IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, |
| 46 | wh, "data", "invalid dir 0x%x", dir); |
| 47 | @@ -3558,6 +3563,11 @@ ieee80211_recv_mgmt(struct ieee80211vap |
| 48 | } else if ((vap->iv_opmode == IEEE80211_M_WDS) && vap->iv_wdsnode) { |
| 49 | found = 1; |
| 50 | ni = ni_or_null = vap->iv_wdsnode; |
| 51 | + } else if (vap->iv_opmode == IEEE80211_M_IBSS) { |
| 52 | + ni_or_null = ieee80211_find_node(&ic->ic_sta, wh->i_addr2); |
| 53 | + if (ni_or_null) |
| 54 | + ni = ni_or_null; |
| 55 | + found = 1; |
| 56 | } |
| 57 | IEEE80211_UNLOCK_IRQ(vap->iv_ic); |
| 58 | |
| 59 | @@ -3686,19 +3696,8 @@ ieee80211_recv_mgmt(struct ieee80211vap |
| 60 | vap->iv_stats.is_rx_ssidmismatch++; /*XXX*/ |
| 61 | return; |
| 62 | } |
| 63 | - if (ni == vap->iv_bss) { |
| 64 | - if (vap->iv_opmode == IEEE80211_M_IBSS) { |
| 65 | - /* |
| 66 | - * XXX Cannot tell if the sender is operating |
| 67 | - * in ibss mode. But we need a new node to |
| 68 | - * send the response so blindly add them to the |
| 69 | - * neighbor table. |
| 70 | - */ |
| 71 | - ni = ieee80211_fakeup_adhoc_node(vap, |
| 72 | - wh->i_addr2); |
| 73 | - } else { |
| 74 | - ni = ieee80211_dup_bss(vap, wh->i_addr2, 1); |
| 75 | - } |
| 76 | + if (ni == vap->iv_bss && vap->iv_opmode != IEEE80211_M_IBSS) { |
| 77 | + ni = ieee80211_dup_bss(vap, wh->i_addr2, 1); |
| 78 | if (ni == NULL) |
| 79 | return; |
| 80 | allocbs = 1; |
| 81 | --- a/net80211/ieee80211_node.c |
| 82 | +++ b/net80211/ieee80211_node.c |
| 83 | @@ -601,6 +601,8 @@ ieee80211_ibss_merge(struct ieee80211_no |
| 84 | ic->ic_flags & IEEE80211_F_SHPREAMBLE ? "short" : "long", |
| 85 | ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", |
| 86 | ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : ""); |
| 87 | + if (!IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bssid)) |
| 88 | + ieee80211_node_table_reset(&vap->iv_ic->ic_sta, vap); |
| 89 | return ieee80211_sta_join1(ieee80211_ref_node(ni)); |
| 90 | } |
| 91 | EXPORT_SYMBOL(ieee80211_ibss_merge); |
| 92 | |