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 | |