Commit 3cde38e7f3491ea62429556149713b7a875c9ac2

Authored by Bob Copeland
Committed by Johannes Berg
1 parent 1daa37c7ba

mac80211: fix off-by-one in llid check.

According to IEEE 802.11-2012 (8.4.2.104), no peering
management element exists with length 7. This code is checking
to see if llid is present to ignore close frames with different
llid, which would be IEs with length 8.

Signed-off-by: Bob Copeland <bob@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

Showing 1 changed file with 1 additions and 1 deletions Inline Diff

net/mac80211/mesh_plink.c
1 /* 1 /*
2 * Copyright (c) 2008, 2009 open80211s Ltd. 2 * Copyright (c) 2008, 2009 open80211s Ltd.
3 * Author: Luis Carlos Cobo <luisca@cozybit.com> 3 * Author: Luis Carlos Cobo <luisca@cozybit.com>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 */ 8 */
9 #include <linux/gfp.h> 9 #include <linux/gfp.h>
10 #include <linux/kernel.h> 10 #include <linux/kernel.h>
11 #include <linux/random.h> 11 #include <linux/random.h>
12 #include "ieee80211_i.h" 12 #include "ieee80211_i.h"
13 #include "rate.h" 13 #include "rate.h"
14 #include "mesh.h" 14 #include "mesh.h"
15 15
16 #define PLINK_GET_LLID(p) (p + 2) 16 #define PLINK_GET_LLID(p) (p + 2)
17 #define PLINK_GET_PLID(p) (p + 4) 17 #define PLINK_GET_PLID(p) (p + 4)
18 18
19 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 19 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
20 jiffies + HZ * t / 1000)) 20 jiffies + HZ * t / 1000))
21 21
22 /* We only need a valid sta if user configured a minimum rssi_threshold. */ 22 /* We only need a valid sta if user configured a minimum rssi_threshold. */
23 #define rssi_threshold_check(sta, sdata) \ 23 #define rssi_threshold_check(sta, sdata) \
24 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\ 24 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
25 (sta && (s8) -ewma_read(&sta->avg_signal) > \ 25 (sta && (s8) -ewma_read(&sta->avg_signal) > \
26 sdata->u.mesh.mshcfg.rssi_threshold)) 26 sdata->u.mesh.mshcfg.rssi_threshold))
27 27
28 enum plink_event { 28 enum plink_event {
29 PLINK_UNDEFINED, 29 PLINK_UNDEFINED,
30 OPN_ACPT, 30 OPN_ACPT,
31 OPN_RJCT, 31 OPN_RJCT,
32 OPN_IGNR, 32 OPN_IGNR,
33 CNF_ACPT, 33 CNF_ACPT,
34 CNF_RJCT, 34 CNF_RJCT,
35 CNF_IGNR, 35 CNF_IGNR,
36 CLS_ACPT, 36 CLS_ACPT,
37 CLS_IGNR 37 CLS_IGNR
38 }; 38 };
39 39
40 static const char * const mplstates[] = { 40 static const char * const mplstates[] = {
41 [NL80211_PLINK_LISTEN] = "LISTEN", 41 [NL80211_PLINK_LISTEN] = "LISTEN",
42 [NL80211_PLINK_OPN_SNT] = "OPN-SNT", 42 [NL80211_PLINK_OPN_SNT] = "OPN-SNT",
43 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD", 43 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
44 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD", 44 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
45 [NL80211_PLINK_ESTAB] = "ESTAB", 45 [NL80211_PLINK_ESTAB] = "ESTAB",
46 [NL80211_PLINK_HOLDING] = "HOLDING", 46 [NL80211_PLINK_HOLDING] = "HOLDING",
47 [NL80211_PLINK_BLOCKED] = "BLOCKED" 47 [NL80211_PLINK_BLOCKED] = "BLOCKED"
48 }; 48 };
49 49
50 static const char * const mplevents[] = { 50 static const char * const mplevents[] = {
51 [PLINK_UNDEFINED] = "NONE", 51 [PLINK_UNDEFINED] = "NONE",
52 [OPN_ACPT] = "OPN_ACPT", 52 [OPN_ACPT] = "OPN_ACPT",
53 [OPN_RJCT] = "OPN_RJCT", 53 [OPN_RJCT] = "OPN_RJCT",
54 [OPN_IGNR] = "OPN_IGNR", 54 [OPN_IGNR] = "OPN_IGNR",
55 [CNF_ACPT] = "CNF_ACPT", 55 [CNF_ACPT] = "CNF_ACPT",
56 [CNF_RJCT] = "CNF_RJCT", 56 [CNF_RJCT] = "CNF_RJCT",
57 [CNF_IGNR] = "CNF_IGNR", 57 [CNF_IGNR] = "CNF_IGNR",
58 [CLS_ACPT] = "CLS_ACPT", 58 [CLS_ACPT] = "CLS_ACPT",
59 [CLS_IGNR] = "CLS_IGNR" 59 [CLS_IGNR] = "CLS_IGNR"
60 }; 60 };
61 61
62 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 62 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
63 enum ieee80211_self_protected_actioncode action, 63 enum ieee80211_self_protected_actioncode action,
64 u8 *da, __le16 llid, __le16 plid, __le16 reason); 64 u8 *da, __le16 llid, __le16 plid, __le16 reason);
65 65
66 /** 66 /**
67 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine 67 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
68 * 68 *
69 * @sta: mesh peer link to restart 69 * @sta: mesh peer link to restart
70 * 70 *
71 * Locking: this function must be called holding sta->lock 71 * Locking: this function must be called holding sta->lock
72 */ 72 */
73 static inline void mesh_plink_fsm_restart(struct sta_info *sta) 73 static inline void mesh_plink_fsm_restart(struct sta_info *sta)
74 { 74 {
75 sta->plink_state = NL80211_PLINK_LISTEN; 75 sta->plink_state = NL80211_PLINK_LISTEN;
76 sta->llid = sta->plid = sta->reason = 0; 76 sta->llid = sta->plid = sta->reason = 0;
77 sta->plink_retries = 0; 77 sta->plink_retries = 0;
78 } 78 }
79 79
80 /* 80 /*
81 * mesh_set_short_slot_time - enable / disable ERP short slot time. 81 * mesh_set_short_slot_time - enable / disable ERP short slot time.
82 * 82 *
83 * The standard indirectly mandates mesh STAs to turn off short slot time by 83 * The standard indirectly mandates mesh STAs to turn off short slot time by
84 * disallowing advertising this (802.11-2012 8.4.1.4), but that doesn't mean we 84 * disallowing advertising this (802.11-2012 8.4.1.4), but that doesn't mean we
85 * can't be sneaky about it. Enable short slot time if all mesh STAs in the 85 * can't be sneaky about it. Enable short slot time if all mesh STAs in the
86 * MBSS support ERP rates. 86 * MBSS support ERP rates.
87 * 87 *
88 * Returns BSS_CHANGED_ERP_SLOT or 0 for no change. 88 * Returns BSS_CHANGED_ERP_SLOT or 0 for no change.
89 */ 89 */
90 static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata) 90 static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
91 { 91 {
92 struct ieee80211_local *local = sdata->local; 92 struct ieee80211_local *local = sdata->local;
93 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 93 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
94 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 94 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
95 struct sta_info *sta; 95 struct sta_info *sta;
96 u32 erp_rates = 0, changed = 0; 96 u32 erp_rates = 0, changed = 0;
97 int i; 97 int i;
98 bool short_slot = false; 98 bool short_slot = false;
99 99
100 if (band == IEEE80211_BAND_5GHZ) { 100 if (band == IEEE80211_BAND_5GHZ) {
101 /* (IEEE 802.11-2012 19.4.5) */ 101 /* (IEEE 802.11-2012 19.4.5) */
102 short_slot = true; 102 short_slot = true;
103 goto out; 103 goto out;
104 } else if (band != IEEE80211_BAND_2GHZ || 104 } else if (band != IEEE80211_BAND_2GHZ ||
105 (band == IEEE80211_BAND_2GHZ && 105 (band == IEEE80211_BAND_2GHZ &&
106 local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) 106 local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
107 goto out; 107 goto out;
108 108
109 for (i = 0; i < sband->n_bitrates; i++) 109 for (i = 0; i < sband->n_bitrates; i++)
110 if (sband->bitrates[i].flags & IEEE80211_RATE_ERP_G) 110 if (sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)
111 erp_rates |= BIT(i); 111 erp_rates |= BIT(i);
112 112
113 if (!erp_rates) 113 if (!erp_rates)
114 goto out; 114 goto out;
115 115
116 rcu_read_lock(); 116 rcu_read_lock();
117 list_for_each_entry_rcu(sta, &local->sta_list, list) { 117 list_for_each_entry_rcu(sta, &local->sta_list, list) {
118 if (sdata != sta->sdata || 118 if (sdata != sta->sdata ||
119 sta->plink_state != NL80211_PLINK_ESTAB) 119 sta->plink_state != NL80211_PLINK_ESTAB)
120 continue; 120 continue;
121 121
122 short_slot = false; 122 short_slot = false;
123 if (erp_rates & sta->sta.supp_rates[band]) 123 if (erp_rates & sta->sta.supp_rates[band])
124 short_slot = true; 124 short_slot = true;
125 else 125 else
126 break; 126 break;
127 } 127 }
128 rcu_read_unlock(); 128 rcu_read_unlock();
129 129
130 out: 130 out:
131 if (sdata->vif.bss_conf.use_short_slot != short_slot) { 131 if (sdata->vif.bss_conf.use_short_slot != short_slot) {
132 sdata->vif.bss_conf.use_short_slot = short_slot; 132 sdata->vif.bss_conf.use_short_slot = short_slot;
133 changed = BSS_CHANGED_ERP_SLOT; 133 changed = BSS_CHANGED_ERP_SLOT;
134 mpl_dbg(sdata, "mesh_plink %pM: ERP short slot time %d\n", 134 mpl_dbg(sdata, "mesh_plink %pM: ERP short slot time %d\n",
135 sdata->vif.addr, short_slot); 135 sdata->vif.addr, short_slot);
136 } 136 }
137 return changed; 137 return changed;
138 } 138 }
139 139
140 /** 140 /**
141 * mesh_set_ht_prot_mode - set correct HT protection mode 141 * mesh_set_ht_prot_mode - set correct HT protection mode
142 * 142 *
143 * Section 9.23.3.5 of IEEE 80211-2012 describes the protection rules for HT 143 * Section 9.23.3.5 of IEEE 80211-2012 describes the protection rules for HT
144 * mesh STA in a MBSS. Three HT protection modes are supported for now, non-HT 144 * mesh STA in a MBSS. Three HT protection modes are supported for now, non-HT
145 * mixed mode, 20MHz-protection and no-protection mode. non-HT mixed mode is 145 * mixed mode, 20MHz-protection and no-protection mode. non-HT mixed mode is
146 * selected if any non-HT peers are present in our MBSS. 20MHz-protection mode 146 * selected if any non-HT peers are present in our MBSS. 20MHz-protection mode
147 * is selected if all peers in our 20/40MHz MBSS support HT and atleast one 147 * is selected if all peers in our 20/40MHz MBSS support HT and atleast one
148 * HT20 peer is present. Otherwise no-protection mode is selected. 148 * HT20 peer is present. Otherwise no-protection mode is selected.
149 */ 149 */
150 static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) 150 static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
151 { 151 {
152 struct ieee80211_local *local = sdata->local; 152 struct ieee80211_local *local = sdata->local;
153 struct sta_info *sta; 153 struct sta_info *sta;
154 u16 ht_opmode; 154 u16 ht_opmode;
155 bool non_ht_sta = false, ht20_sta = false; 155 bool non_ht_sta = false, ht20_sta = false;
156 156
157 switch (sdata->vif.bss_conf.chandef.width) { 157 switch (sdata->vif.bss_conf.chandef.width) {
158 case NL80211_CHAN_WIDTH_20_NOHT: 158 case NL80211_CHAN_WIDTH_20_NOHT:
159 case NL80211_CHAN_WIDTH_5: 159 case NL80211_CHAN_WIDTH_5:
160 case NL80211_CHAN_WIDTH_10: 160 case NL80211_CHAN_WIDTH_10:
161 return 0; 161 return 0;
162 default: 162 default:
163 break; 163 break;
164 } 164 }
165 165
166 rcu_read_lock(); 166 rcu_read_lock();
167 list_for_each_entry_rcu(sta, &local->sta_list, list) { 167 list_for_each_entry_rcu(sta, &local->sta_list, list) {
168 if (sdata != sta->sdata || 168 if (sdata != sta->sdata ||
169 sta->plink_state != NL80211_PLINK_ESTAB) 169 sta->plink_state != NL80211_PLINK_ESTAB)
170 continue; 170 continue;
171 171
172 if (sta->sta.bandwidth > IEEE80211_STA_RX_BW_20) 172 if (sta->sta.bandwidth > IEEE80211_STA_RX_BW_20)
173 continue; 173 continue;
174 174
175 if (!sta->sta.ht_cap.ht_supported) { 175 if (!sta->sta.ht_cap.ht_supported) {
176 mpl_dbg(sdata, "nonHT sta (%pM) is present\n", 176 mpl_dbg(sdata, "nonHT sta (%pM) is present\n",
177 sta->sta.addr); 177 sta->sta.addr);
178 non_ht_sta = true; 178 non_ht_sta = true;
179 break; 179 break;
180 } 180 }
181 181
182 mpl_dbg(sdata, "HT20 sta (%pM) is present\n", sta->sta.addr); 182 mpl_dbg(sdata, "HT20 sta (%pM) is present\n", sta->sta.addr);
183 ht20_sta = true; 183 ht20_sta = true;
184 } 184 }
185 rcu_read_unlock(); 185 rcu_read_unlock();
186 186
187 if (non_ht_sta) 187 if (non_ht_sta)
188 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED; 188 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
189 else if (ht20_sta && 189 else if (ht20_sta &&
190 sdata->vif.bss_conf.chandef.width > NL80211_CHAN_WIDTH_20) 190 sdata->vif.bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
191 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ; 191 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
192 else 192 else
193 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE; 193 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
194 194
195 if (sdata->vif.bss_conf.ht_operation_mode == ht_opmode) 195 if (sdata->vif.bss_conf.ht_operation_mode == ht_opmode)
196 return 0; 196 return 0;
197 197
198 sdata->vif.bss_conf.ht_operation_mode = ht_opmode; 198 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
199 sdata->u.mesh.mshcfg.ht_opmode = ht_opmode; 199 sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
200 mpl_dbg(sdata, "selected new HT protection mode %d\n", ht_opmode); 200 mpl_dbg(sdata, "selected new HT protection mode %d\n", ht_opmode);
201 return BSS_CHANGED_HT; 201 return BSS_CHANGED_HT;
202 } 202 }
203 203
204 /** 204 /**
205 * __mesh_plink_deactivate - deactivate mesh peer link 205 * __mesh_plink_deactivate - deactivate mesh peer link
206 * 206 *
207 * @sta: mesh peer link to deactivate 207 * @sta: mesh peer link to deactivate
208 * 208 *
209 * All mesh paths with this peer as next hop will be flushed 209 * All mesh paths with this peer as next hop will be flushed
210 * Returns beacon changed flag if the beacon content changed. 210 * Returns beacon changed flag if the beacon content changed.
211 * 211 *
212 * Locking: the caller must hold sta->lock 212 * Locking: the caller must hold sta->lock
213 */ 213 */
214 static u32 __mesh_plink_deactivate(struct sta_info *sta) 214 static u32 __mesh_plink_deactivate(struct sta_info *sta)
215 { 215 {
216 struct ieee80211_sub_if_data *sdata = sta->sdata; 216 struct ieee80211_sub_if_data *sdata = sta->sdata;
217 u32 changed = 0; 217 u32 changed = 0;
218 218
219 if (sta->plink_state == NL80211_PLINK_ESTAB) 219 if (sta->plink_state == NL80211_PLINK_ESTAB)
220 changed = mesh_plink_dec_estab_count(sdata); 220 changed = mesh_plink_dec_estab_count(sdata);
221 sta->plink_state = NL80211_PLINK_BLOCKED; 221 sta->plink_state = NL80211_PLINK_BLOCKED;
222 mesh_path_flush_by_nexthop(sta); 222 mesh_path_flush_by_nexthop(sta);
223 223
224 ieee80211_mps_sta_status_update(sta); 224 ieee80211_mps_sta_status_update(sta);
225 changed |= ieee80211_mps_set_sta_local_pm(sta, 225 changed |= ieee80211_mps_set_sta_local_pm(sta,
226 NL80211_MESH_POWER_UNKNOWN); 226 NL80211_MESH_POWER_UNKNOWN);
227 227
228 return changed; 228 return changed;
229 } 229 }
230 230
231 /** 231 /**
232 * mesh_plink_deactivate - deactivate mesh peer link 232 * mesh_plink_deactivate - deactivate mesh peer link
233 * 233 *
234 * @sta: mesh peer link to deactivate 234 * @sta: mesh peer link to deactivate
235 * 235 *
236 * All mesh paths with this peer as next hop will be flushed 236 * All mesh paths with this peer as next hop will be flushed
237 */ 237 */
238 u32 mesh_plink_deactivate(struct sta_info *sta) 238 u32 mesh_plink_deactivate(struct sta_info *sta)
239 { 239 {
240 struct ieee80211_sub_if_data *sdata = sta->sdata; 240 struct ieee80211_sub_if_data *sdata = sta->sdata;
241 u32 changed; 241 u32 changed;
242 242
243 spin_lock_bh(&sta->lock); 243 spin_lock_bh(&sta->lock);
244 changed = __mesh_plink_deactivate(sta); 244 changed = __mesh_plink_deactivate(sta);
245 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED); 245 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED);
246 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 246 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
247 sta->sta.addr, sta->llid, sta->plid, 247 sta->sta.addr, sta->llid, sta->plid,
248 sta->reason); 248 sta->reason);
249 spin_unlock_bh(&sta->lock); 249 spin_unlock_bh(&sta->lock);
250 250
251 return changed; 251 return changed;
252 } 252 }
253 253
254 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 254 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
255 enum ieee80211_self_protected_actioncode action, 255 enum ieee80211_self_protected_actioncode action,
256 u8 *da, __le16 llid, __le16 plid, __le16 reason) 256 u8 *da, __le16 llid, __le16 plid, __le16 reason)
257 { 257 {
258 struct ieee80211_local *local = sdata->local; 258 struct ieee80211_local *local = sdata->local;
259 struct sk_buff *skb; 259 struct sk_buff *skb;
260 struct ieee80211_tx_info *info; 260 struct ieee80211_tx_info *info;
261 struct ieee80211_mgmt *mgmt; 261 struct ieee80211_mgmt *mgmt;
262 bool include_plid = false; 262 bool include_plid = false;
263 u16 peering_proto = 0; 263 u16 peering_proto = 0;
264 u8 *pos, ie_len = 4; 264 u8 *pos, ie_len = 4;
265 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) + 265 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) +
266 sizeof(mgmt->u.action.u.self_prot); 266 sizeof(mgmt->u.action.u.self_prot);
267 int err = -ENOMEM; 267 int err = -ENOMEM;
268 268
269 skb = dev_alloc_skb(local->tx_headroom + 269 skb = dev_alloc_skb(local->tx_headroom +
270 hdr_len + 270 hdr_len +
271 2 + /* capability info */ 271 2 + /* capability info */
272 2 + /* AID */ 272 2 + /* AID */
273 2 + 8 + /* supported rates */ 273 2 + 8 + /* supported rates */
274 2 + (IEEE80211_MAX_SUPP_RATES - 8) + 274 2 + (IEEE80211_MAX_SUPP_RATES - 8) +
275 2 + sdata->u.mesh.mesh_id_len + 275 2 + sdata->u.mesh.mesh_id_len +
276 2 + sizeof(struct ieee80211_meshconf_ie) + 276 2 + sizeof(struct ieee80211_meshconf_ie) +
277 2 + sizeof(struct ieee80211_ht_cap) + 277 2 + sizeof(struct ieee80211_ht_cap) +
278 2 + sizeof(struct ieee80211_ht_operation) + 278 2 + sizeof(struct ieee80211_ht_operation) +
279 2 + 8 + /* peering IE */ 279 2 + 8 + /* peering IE */
280 sdata->u.mesh.ie_len); 280 sdata->u.mesh.ie_len);
281 if (!skb) 281 if (!skb)
282 return -1; 282 return -1;
283 info = IEEE80211_SKB_CB(skb); 283 info = IEEE80211_SKB_CB(skb);
284 skb_reserve(skb, local->tx_headroom); 284 skb_reserve(skb, local->tx_headroom);
285 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); 285 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
286 memset(mgmt, 0, hdr_len); 286 memset(mgmt, 0, hdr_len);
287 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 287 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
288 IEEE80211_STYPE_ACTION); 288 IEEE80211_STYPE_ACTION);
289 memcpy(mgmt->da, da, ETH_ALEN); 289 memcpy(mgmt->da, da, ETH_ALEN);
290 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 290 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
291 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 291 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
292 mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED; 292 mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
293 mgmt->u.action.u.self_prot.action_code = action; 293 mgmt->u.action.u.self_prot.action_code = action;
294 294
295 if (action != WLAN_SP_MESH_PEERING_CLOSE) { 295 if (action != WLAN_SP_MESH_PEERING_CLOSE) {
296 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 296 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
297 297
298 /* capability info */ 298 /* capability info */
299 pos = skb_put(skb, 2); 299 pos = skb_put(skb, 2);
300 memset(pos, 0, 2); 300 memset(pos, 0, 2);
301 if (action == WLAN_SP_MESH_PEERING_CONFIRM) { 301 if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
302 /* AID */ 302 /* AID */
303 pos = skb_put(skb, 2); 303 pos = skb_put(skb, 2);
304 memcpy(pos + 2, &plid, 2); 304 memcpy(pos + 2, &plid, 2);
305 } 305 }
306 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 306 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
307 ieee80211_add_ext_srates_ie(sdata, skb, true, band) || 307 ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
308 mesh_add_rsn_ie(sdata, skb) || 308 mesh_add_rsn_ie(sdata, skb) ||
309 mesh_add_meshid_ie(sdata, skb) || 309 mesh_add_meshid_ie(sdata, skb) ||
310 mesh_add_meshconf_ie(sdata, skb)) 310 mesh_add_meshconf_ie(sdata, skb))
311 goto free; 311 goto free;
312 } else { /* WLAN_SP_MESH_PEERING_CLOSE */ 312 } else { /* WLAN_SP_MESH_PEERING_CLOSE */
313 info->flags |= IEEE80211_TX_CTL_NO_ACK; 313 info->flags |= IEEE80211_TX_CTL_NO_ACK;
314 if (mesh_add_meshid_ie(sdata, skb)) 314 if (mesh_add_meshid_ie(sdata, skb))
315 goto free; 315 goto free;
316 } 316 }
317 317
318 /* Add Mesh Peering Management element */ 318 /* Add Mesh Peering Management element */
319 switch (action) { 319 switch (action) {
320 case WLAN_SP_MESH_PEERING_OPEN: 320 case WLAN_SP_MESH_PEERING_OPEN:
321 break; 321 break;
322 case WLAN_SP_MESH_PEERING_CONFIRM: 322 case WLAN_SP_MESH_PEERING_CONFIRM:
323 ie_len += 2; 323 ie_len += 2;
324 include_plid = true; 324 include_plid = true;
325 break; 325 break;
326 case WLAN_SP_MESH_PEERING_CLOSE: 326 case WLAN_SP_MESH_PEERING_CLOSE:
327 if (plid) { 327 if (plid) {
328 ie_len += 2; 328 ie_len += 2;
329 include_plid = true; 329 include_plid = true;
330 } 330 }
331 ie_len += 2; /* reason code */ 331 ie_len += 2; /* reason code */
332 break; 332 break;
333 default: 333 default:
334 err = -EINVAL; 334 err = -EINVAL;
335 goto free; 335 goto free;
336 } 336 }
337 337
338 if (WARN_ON(skb_tailroom(skb) < 2 + ie_len)) 338 if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
339 goto free; 339 goto free;
340 340
341 pos = skb_put(skb, 2 + ie_len); 341 pos = skb_put(skb, 2 + ie_len);
342 *pos++ = WLAN_EID_PEER_MGMT; 342 *pos++ = WLAN_EID_PEER_MGMT;
343 *pos++ = ie_len; 343 *pos++ = ie_len;
344 memcpy(pos, &peering_proto, 2); 344 memcpy(pos, &peering_proto, 2);
345 pos += 2; 345 pos += 2;
346 memcpy(pos, &llid, 2); 346 memcpy(pos, &llid, 2);
347 pos += 2; 347 pos += 2;
348 if (include_plid) { 348 if (include_plid) {
349 memcpy(pos, &plid, 2); 349 memcpy(pos, &plid, 2);
350 pos += 2; 350 pos += 2;
351 } 351 }
352 if (action == WLAN_SP_MESH_PEERING_CLOSE) { 352 if (action == WLAN_SP_MESH_PEERING_CLOSE) {
353 memcpy(pos, &reason, 2); 353 memcpy(pos, &reason, 2);
354 pos += 2; 354 pos += 2;
355 } 355 }
356 356
357 if (action != WLAN_SP_MESH_PEERING_CLOSE) { 357 if (action != WLAN_SP_MESH_PEERING_CLOSE) {
358 if (mesh_add_ht_cap_ie(sdata, skb) || 358 if (mesh_add_ht_cap_ie(sdata, skb) ||
359 mesh_add_ht_oper_ie(sdata, skb)) 359 mesh_add_ht_oper_ie(sdata, skb))
360 goto free; 360 goto free;
361 } 361 }
362 362
363 if (mesh_add_vendor_ies(sdata, skb)) 363 if (mesh_add_vendor_ies(sdata, skb))
364 goto free; 364 goto free;
365 365
366 ieee80211_tx_skb(sdata, skb); 366 ieee80211_tx_skb(sdata, skb);
367 return 0; 367 return 0;
368 free: 368 free:
369 kfree_skb(skb); 369 kfree_skb(skb);
370 return err; 370 return err;
371 } 371 }
372 372
373 static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, 373 static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
374 struct sta_info *sta, 374 struct sta_info *sta,
375 struct ieee802_11_elems *elems, bool insert) 375 struct ieee802_11_elems *elems, bool insert)
376 { 376 {
377 struct ieee80211_local *local = sdata->local; 377 struct ieee80211_local *local = sdata->local;
378 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 378 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
379 struct ieee80211_supported_band *sband; 379 struct ieee80211_supported_band *sband;
380 u32 rates, basic_rates = 0, changed = 0; 380 u32 rates, basic_rates = 0, changed = 0;
381 381
382 sband = local->hw.wiphy->bands[band]; 382 sband = local->hw.wiphy->bands[band];
383 rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates); 383 rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
384 384
385 spin_lock_bh(&sta->lock); 385 spin_lock_bh(&sta->lock);
386 sta->last_rx = jiffies; 386 sta->last_rx = jiffies;
387 387
388 /* rates and capabilities don't change during peering */ 388 /* rates and capabilities don't change during peering */
389 if (sta->plink_state == NL80211_PLINK_ESTAB) 389 if (sta->plink_state == NL80211_PLINK_ESTAB)
390 goto out; 390 goto out;
391 391
392 if (sta->sta.supp_rates[band] != rates) 392 if (sta->sta.supp_rates[band] != rates)
393 changed |= IEEE80211_RC_SUPP_RATES_CHANGED; 393 changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
394 sta->sta.supp_rates[band] = rates; 394 sta->sta.supp_rates[band] = rates;
395 395
396 if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 396 if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
397 elems->ht_cap_elem, sta)) 397 elems->ht_cap_elem, sta))
398 changed |= IEEE80211_RC_BW_CHANGED; 398 changed |= IEEE80211_RC_BW_CHANGED;
399 399
400 /* HT peer is operating 20MHz-only */ 400 /* HT peer is operating 20MHz-only */
401 if (elems->ht_operation && 401 if (elems->ht_operation &&
402 !(elems->ht_operation->ht_param & 402 !(elems->ht_operation->ht_param &
403 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { 403 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
404 if (sta->sta.bandwidth != IEEE80211_STA_RX_BW_20) 404 if (sta->sta.bandwidth != IEEE80211_STA_RX_BW_20)
405 changed |= IEEE80211_RC_BW_CHANGED; 405 changed |= IEEE80211_RC_BW_CHANGED;
406 sta->sta.bandwidth = IEEE80211_STA_RX_BW_20; 406 sta->sta.bandwidth = IEEE80211_STA_RX_BW_20;
407 } 407 }
408 408
409 if (insert) 409 if (insert)
410 rate_control_rate_init(sta); 410 rate_control_rate_init(sta);
411 else 411 else
412 rate_control_rate_update(local, sband, sta, changed); 412 rate_control_rate_update(local, sband, sta, changed);
413 out: 413 out:
414 spin_unlock_bh(&sta->lock); 414 spin_unlock_bh(&sta->lock);
415 } 415 }
416 416
417 static struct sta_info * 417 static struct sta_info *
418 __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr) 418 __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr)
419 { 419 {
420 struct sta_info *sta; 420 struct sta_info *sta;
421 421
422 if (sdata->local->num_sta >= MESH_MAX_PLINKS) 422 if (sdata->local->num_sta >= MESH_MAX_PLINKS)
423 return NULL; 423 return NULL;
424 424
425 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL); 425 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
426 if (!sta) 426 if (!sta)
427 return NULL; 427 return NULL;
428 428
429 sta->plink_state = NL80211_PLINK_LISTEN; 429 sta->plink_state = NL80211_PLINK_LISTEN;
430 430
431 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); 431 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
432 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); 432 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
433 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); 433 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
434 434
435 set_sta_flag(sta, WLAN_STA_WME); 435 set_sta_flag(sta, WLAN_STA_WME);
436 436
437 return sta; 437 return sta;
438 } 438 }
439 439
440 static struct sta_info * 440 static struct sta_info *
441 mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr, 441 mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
442 struct ieee802_11_elems *elems) 442 struct ieee802_11_elems *elems)
443 { 443 {
444 struct sta_info *sta = NULL; 444 struct sta_info *sta = NULL;
445 445
446 /* Userspace handles station allocation */ 446 /* Userspace handles station allocation */
447 if (sdata->u.mesh.user_mpm || 447 if (sdata->u.mesh.user_mpm ||
448 sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) 448 sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
449 cfg80211_notify_new_peer_candidate(sdata->dev, addr, 449 cfg80211_notify_new_peer_candidate(sdata->dev, addr,
450 elems->ie_start, 450 elems->ie_start,
451 elems->total_len, 451 elems->total_len,
452 GFP_KERNEL); 452 GFP_KERNEL);
453 else 453 else
454 sta = __mesh_sta_info_alloc(sdata, addr); 454 sta = __mesh_sta_info_alloc(sdata, addr);
455 455
456 return sta; 456 return sta;
457 } 457 }
458 458
459 /* 459 /*
460 * mesh_sta_info_get - return mesh sta info entry for @addr. 460 * mesh_sta_info_get - return mesh sta info entry for @addr.
461 * 461 *
462 * @sdata: local meshif 462 * @sdata: local meshif
463 * @addr: peer's address 463 * @addr: peer's address
464 * @elems: IEs from beacon or mesh peering frame. 464 * @elems: IEs from beacon or mesh peering frame.
465 * 465 *
466 * Return existing or newly allocated sta_info under RCU read lock. 466 * Return existing or newly allocated sta_info under RCU read lock.
467 * (re)initialize with given IEs. 467 * (re)initialize with given IEs.
468 */ 468 */
469 static struct sta_info * 469 static struct sta_info *
470 mesh_sta_info_get(struct ieee80211_sub_if_data *sdata, 470 mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
471 u8 *addr, struct ieee802_11_elems *elems) __acquires(RCU) 471 u8 *addr, struct ieee802_11_elems *elems) __acquires(RCU)
472 { 472 {
473 struct sta_info *sta = NULL; 473 struct sta_info *sta = NULL;
474 474
475 rcu_read_lock(); 475 rcu_read_lock();
476 sta = sta_info_get(sdata, addr); 476 sta = sta_info_get(sdata, addr);
477 if (sta) { 477 if (sta) {
478 mesh_sta_info_init(sdata, sta, elems, false); 478 mesh_sta_info_init(sdata, sta, elems, false);
479 } else { 479 } else {
480 rcu_read_unlock(); 480 rcu_read_unlock();
481 /* can't run atomic */ 481 /* can't run atomic */
482 sta = mesh_sta_info_alloc(sdata, addr, elems); 482 sta = mesh_sta_info_alloc(sdata, addr, elems);
483 if (!sta) { 483 if (!sta) {
484 rcu_read_lock(); 484 rcu_read_lock();
485 return NULL; 485 return NULL;
486 } 486 }
487 487
488 mesh_sta_info_init(sdata, sta, elems, true); 488 mesh_sta_info_init(sdata, sta, elems, true);
489 489
490 if (sta_info_insert_rcu(sta)) 490 if (sta_info_insert_rcu(sta))
491 return NULL; 491 return NULL;
492 } 492 }
493 493
494 return sta; 494 return sta;
495 } 495 }
496 496
497 /* 497 /*
498 * mesh_neighbour_update - update or initialize new mesh neighbor. 498 * mesh_neighbour_update - update or initialize new mesh neighbor.
499 * 499 *
500 * @sdata: local meshif 500 * @sdata: local meshif
501 * @addr: peer's address 501 * @addr: peer's address
502 * @elems: IEs from beacon or mesh peering frame 502 * @elems: IEs from beacon or mesh peering frame
503 * 503 *
504 * Initiates peering if appropriate. 504 * Initiates peering if appropriate.
505 */ 505 */
506 void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, 506 void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
507 u8 *hw_addr, 507 u8 *hw_addr,
508 struct ieee802_11_elems *elems) 508 struct ieee802_11_elems *elems)
509 { 509 {
510 struct sta_info *sta; 510 struct sta_info *sta;
511 u32 changed = 0; 511 u32 changed = 0;
512 512
513 sta = mesh_sta_info_get(sdata, hw_addr, elems); 513 sta = mesh_sta_info_get(sdata, hw_addr, elems);
514 if (!sta) 514 if (!sta)
515 goto out; 515 goto out;
516 516
517 if (mesh_peer_accepts_plinks(elems) && 517 if (mesh_peer_accepts_plinks(elems) &&
518 sta->plink_state == NL80211_PLINK_LISTEN && 518 sta->plink_state == NL80211_PLINK_LISTEN &&
519 sdata->u.mesh.accepting_plinks && 519 sdata->u.mesh.accepting_plinks &&
520 sdata->u.mesh.mshcfg.auto_open_plinks && 520 sdata->u.mesh.mshcfg.auto_open_plinks &&
521 rssi_threshold_check(sta, sdata)) 521 rssi_threshold_check(sta, sdata))
522 changed = mesh_plink_open(sta); 522 changed = mesh_plink_open(sta);
523 523
524 ieee80211_mps_frame_release(sta, elems); 524 ieee80211_mps_frame_release(sta, elems);
525 out: 525 out:
526 rcu_read_unlock(); 526 rcu_read_unlock();
527 ieee80211_mbss_info_change_notify(sdata, changed); 527 ieee80211_mbss_info_change_notify(sdata, changed);
528 } 528 }
529 529
530 static void mesh_plink_timer(unsigned long data) 530 static void mesh_plink_timer(unsigned long data)
531 { 531 {
532 struct sta_info *sta; 532 struct sta_info *sta;
533 __le16 llid, plid, reason; 533 __le16 llid, plid, reason;
534 struct ieee80211_sub_if_data *sdata; 534 struct ieee80211_sub_if_data *sdata;
535 struct mesh_config *mshcfg; 535 struct mesh_config *mshcfg;
536 536
537 /* 537 /*
538 * This STA is valid because sta_info_destroy() will 538 * This STA is valid because sta_info_destroy() will
539 * del_timer_sync() this timer after having made sure 539 * del_timer_sync() this timer after having made sure
540 * it cannot be readded (by deleting the plink.) 540 * it cannot be readded (by deleting the plink.)
541 */ 541 */
542 sta = (struct sta_info *) data; 542 sta = (struct sta_info *) data;
543 543
544 if (sta->sdata->local->quiescing) 544 if (sta->sdata->local->quiescing)
545 return; 545 return;
546 546
547 spin_lock_bh(&sta->lock); 547 spin_lock_bh(&sta->lock);
548 if (sta->ignore_plink_timer) { 548 if (sta->ignore_plink_timer) {
549 sta->ignore_plink_timer = false; 549 sta->ignore_plink_timer = false;
550 spin_unlock_bh(&sta->lock); 550 spin_unlock_bh(&sta->lock);
551 return; 551 return;
552 } 552 }
553 mpl_dbg(sta->sdata, 553 mpl_dbg(sta->sdata,
554 "Mesh plink timer for %pM fired on state %s\n", 554 "Mesh plink timer for %pM fired on state %s\n",
555 sta->sta.addr, mplstates[sta->plink_state]); 555 sta->sta.addr, mplstates[sta->plink_state]);
556 reason = 0; 556 reason = 0;
557 llid = sta->llid; 557 llid = sta->llid;
558 plid = sta->plid; 558 plid = sta->plid;
559 sdata = sta->sdata; 559 sdata = sta->sdata;
560 mshcfg = &sdata->u.mesh.mshcfg; 560 mshcfg = &sdata->u.mesh.mshcfg;
561 561
562 switch (sta->plink_state) { 562 switch (sta->plink_state) {
563 case NL80211_PLINK_OPN_RCVD: 563 case NL80211_PLINK_OPN_RCVD:
564 case NL80211_PLINK_OPN_SNT: 564 case NL80211_PLINK_OPN_SNT:
565 /* retry timer */ 565 /* retry timer */
566 if (sta->plink_retries < mshcfg->dot11MeshMaxRetries) { 566 if (sta->plink_retries < mshcfg->dot11MeshMaxRetries) {
567 u32 rand; 567 u32 rand;
568 mpl_dbg(sta->sdata, 568 mpl_dbg(sta->sdata,
569 "Mesh plink for %pM (retry, timeout): %d %d\n", 569 "Mesh plink for %pM (retry, timeout): %d %d\n",
570 sta->sta.addr, sta->plink_retries, 570 sta->sta.addr, sta->plink_retries,
571 sta->plink_timeout); 571 sta->plink_timeout);
572 get_random_bytes(&rand, sizeof(u32)); 572 get_random_bytes(&rand, sizeof(u32));
573 sta->plink_timeout = sta->plink_timeout + 573 sta->plink_timeout = sta->plink_timeout +
574 rand % sta->plink_timeout; 574 rand % sta->plink_timeout;
575 ++sta->plink_retries; 575 ++sta->plink_retries;
576 mod_plink_timer(sta, sta->plink_timeout); 576 mod_plink_timer(sta, sta->plink_timeout);
577 spin_unlock_bh(&sta->lock); 577 spin_unlock_bh(&sta->lock);
578 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 578 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
579 sta->sta.addr, llid, 0, 0); 579 sta->sta.addr, llid, 0, 0);
580 break; 580 break;
581 } 581 }
582 reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES); 582 reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES);
583 /* fall through on else */ 583 /* fall through on else */
584 case NL80211_PLINK_CNF_RCVD: 584 case NL80211_PLINK_CNF_RCVD:
585 /* confirm timer */ 585 /* confirm timer */
586 if (!reason) 586 if (!reason)
587 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT); 587 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
588 sta->plink_state = NL80211_PLINK_HOLDING; 588 sta->plink_state = NL80211_PLINK_HOLDING;
589 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); 589 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
590 spin_unlock_bh(&sta->lock); 590 spin_unlock_bh(&sta->lock);
591 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 591 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
592 sta->sta.addr, llid, plid, reason); 592 sta->sta.addr, llid, plid, reason);
593 break; 593 break;
594 case NL80211_PLINK_HOLDING: 594 case NL80211_PLINK_HOLDING:
595 /* holding timer */ 595 /* holding timer */
596 del_timer(&sta->plink_timer); 596 del_timer(&sta->plink_timer);
597 mesh_plink_fsm_restart(sta); 597 mesh_plink_fsm_restart(sta);
598 spin_unlock_bh(&sta->lock); 598 spin_unlock_bh(&sta->lock);
599 break; 599 break;
600 default: 600 default:
601 spin_unlock_bh(&sta->lock); 601 spin_unlock_bh(&sta->lock);
602 break; 602 break;
603 } 603 }
604 } 604 }
605 605
606 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) 606 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
607 { 607 {
608 sta->plink_timer.expires = jiffies + (HZ * timeout / 1000); 608 sta->plink_timer.expires = jiffies + (HZ * timeout / 1000);
609 sta->plink_timer.data = (unsigned long) sta; 609 sta->plink_timer.data = (unsigned long) sta;
610 sta->plink_timer.function = mesh_plink_timer; 610 sta->plink_timer.function = mesh_plink_timer;
611 sta->plink_timeout = timeout; 611 sta->plink_timeout = timeout;
612 add_timer(&sta->plink_timer); 612 add_timer(&sta->plink_timer);
613 } 613 }
614 614
615 u32 mesh_plink_open(struct sta_info *sta) 615 u32 mesh_plink_open(struct sta_info *sta)
616 { 616 {
617 __le16 llid; 617 __le16 llid;
618 struct ieee80211_sub_if_data *sdata = sta->sdata; 618 struct ieee80211_sub_if_data *sdata = sta->sdata;
619 u32 changed; 619 u32 changed;
620 620
621 if (!test_sta_flag(sta, WLAN_STA_AUTH)) 621 if (!test_sta_flag(sta, WLAN_STA_AUTH))
622 return 0; 622 return 0;
623 623
624 spin_lock_bh(&sta->lock); 624 spin_lock_bh(&sta->lock);
625 get_random_bytes(&llid, 2); 625 get_random_bytes(&llid, 2);
626 sta->llid = llid; 626 sta->llid = llid;
627 if (sta->plink_state != NL80211_PLINK_LISTEN && 627 if (sta->plink_state != NL80211_PLINK_LISTEN &&
628 sta->plink_state != NL80211_PLINK_BLOCKED) { 628 sta->plink_state != NL80211_PLINK_BLOCKED) {
629 spin_unlock_bh(&sta->lock); 629 spin_unlock_bh(&sta->lock);
630 return 0; 630 return 0;
631 } 631 }
632 sta->plink_state = NL80211_PLINK_OPN_SNT; 632 sta->plink_state = NL80211_PLINK_OPN_SNT;
633 mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout); 633 mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
634 spin_unlock_bh(&sta->lock); 634 spin_unlock_bh(&sta->lock);
635 mpl_dbg(sdata, 635 mpl_dbg(sdata,
636 "Mesh plink: starting establishment with %pM\n", 636 "Mesh plink: starting establishment with %pM\n",
637 sta->sta.addr); 637 sta->sta.addr);
638 638
639 /* set the non-peer mode to active during peering */ 639 /* set the non-peer mode to active during peering */
640 changed = ieee80211_mps_local_status_update(sdata); 640 changed = ieee80211_mps_local_status_update(sdata);
641 641
642 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 642 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
643 sta->sta.addr, llid, 0, 0); 643 sta->sta.addr, llid, 0, 0);
644 return changed; 644 return changed;
645 } 645 }
646 646
647 u32 mesh_plink_block(struct sta_info *sta) 647 u32 mesh_plink_block(struct sta_info *sta)
648 { 648 {
649 u32 changed; 649 u32 changed;
650 650
651 spin_lock_bh(&sta->lock); 651 spin_lock_bh(&sta->lock);
652 changed = __mesh_plink_deactivate(sta); 652 changed = __mesh_plink_deactivate(sta);
653 sta->plink_state = NL80211_PLINK_BLOCKED; 653 sta->plink_state = NL80211_PLINK_BLOCKED;
654 spin_unlock_bh(&sta->lock); 654 spin_unlock_bh(&sta->lock);
655 655
656 return changed; 656 return changed;
657 } 657 }
658 658
659 659
660 void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, 660 void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
661 struct ieee80211_mgmt *mgmt, size_t len, 661 struct ieee80211_mgmt *mgmt, size_t len,
662 struct ieee80211_rx_status *rx_status) 662 struct ieee80211_rx_status *rx_status)
663 { 663 {
664 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; 664 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
665 struct ieee802_11_elems elems; 665 struct ieee802_11_elems elems;
666 struct sta_info *sta; 666 struct sta_info *sta;
667 enum plink_event event; 667 enum plink_event event;
668 enum ieee80211_self_protected_actioncode ftype; 668 enum ieee80211_self_protected_actioncode ftype;
669 size_t baselen; 669 size_t baselen;
670 bool matches_local = true; 670 bool matches_local = true;
671 u8 ie_len; 671 u8 ie_len;
672 u8 *baseaddr; 672 u8 *baseaddr;
673 u32 changed = 0; 673 u32 changed = 0;
674 __le16 plid, llid, reason; 674 __le16 plid, llid, reason;
675 675
676 /* need action_code, aux */ 676 /* need action_code, aux */
677 if (len < IEEE80211_MIN_ACTION_SIZE + 3) 677 if (len < IEEE80211_MIN_ACTION_SIZE + 3)
678 return; 678 return;
679 679
680 if (sdata->u.mesh.user_mpm) 680 if (sdata->u.mesh.user_mpm)
681 /* userspace must register for these */ 681 /* userspace must register for these */
682 return; 682 return;
683 683
684 if (is_multicast_ether_addr(mgmt->da)) { 684 if (is_multicast_ether_addr(mgmt->da)) {
685 mpl_dbg(sdata, 685 mpl_dbg(sdata,
686 "Mesh plink: ignore frame from multicast address\n"); 686 "Mesh plink: ignore frame from multicast address\n");
687 return; 687 return;
688 } 688 }
689 689
690 baseaddr = mgmt->u.action.u.self_prot.variable; 690 baseaddr = mgmt->u.action.u.self_prot.variable;
691 baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt; 691 baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
692 if (mgmt->u.action.u.self_prot.action_code == 692 if (mgmt->u.action.u.self_prot.action_code ==
693 WLAN_SP_MESH_PEERING_CONFIRM) { 693 WLAN_SP_MESH_PEERING_CONFIRM) {
694 baseaddr += 4; 694 baseaddr += 4;
695 baselen += 4; 695 baselen += 4;
696 } 696 }
697 ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems); 697 ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems);
698 698
699 if (!elems.peering) { 699 if (!elems.peering) {
700 mpl_dbg(sdata, 700 mpl_dbg(sdata,
701 "Mesh plink: missing necessary peer link ie\n"); 701 "Mesh plink: missing necessary peer link ie\n");
702 return; 702 return;
703 } 703 }
704 704
705 if (elems.rsn_len && 705 if (elems.rsn_len &&
706 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 706 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
707 mpl_dbg(sdata, 707 mpl_dbg(sdata,
708 "Mesh plink: can't establish link with secure peer\n"); 708 "Mesh plink: can't establish link with secure peer\n");
709 return; 709 return;
710 } 710 }
711 711
712 ftype = mgmt->u.action.u.self_prot.action_code; 712 ftype = mgmt->u.action.u.self_prot.action_code;
713 ie_len = elems.peering_len; 713 ie_len = elems.peering_len;
714 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) || 714 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
715 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || 715 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
716 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 716 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
717 && ie_len != 8)) { 717 && ie_len != 8)) {
718 mpl_dbg(sdata, 718 mpl_dbg(sdata,
719 "Mesh plink: incorrect plink ie length %d %d\n", 719 "Mesh plink: incorrect plink ie length %d %d\n",
720 ftype, ie_len); 720 ftype, ie_len);
721 return; 721 return;
722 } 722 }
723 723
724 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 724 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
725 (!elems.mesh_id || !elems.mesh_config)) { 725 (!elems.mesh_id || !elems.mesh_config)) {
726 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n"); 726 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
727 return; 727 return;
728 } 728 }
729 /* Note the lines below are correct, the llid in the frame is the plid 729 /* Note the lines below are correct, the llid in the frame is the plid
730 * from the point of view of this host. 730 * from the point of view of this host.
731 */ 731 */
732 memcpy(&plid, PLINK_GET_LLID(elems.peering), 2); 732 memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
733 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM || 733 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
734 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) 734 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
735 memcpy(&llid, PLINK_GET_PLID(elems.peering), 2); 735 memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
736 736
737 /* WARNING: Only for sta pointer, is dropped & re-acquired */ 737 /* WARNING: Only for sta pointer, is dropped & re-acquired */
738 rcu_read_lock(); 738 rcu_read_lock();
739 739
740 sta = sta_info_get(sdata, mgmt->sa); 740 sta = sta_info_get(sdata, mgmt->sa);
741 if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) { 741 if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
742 mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n"); 742 mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
743 rcu_read_unlock(); 743 rcu_read_unlock();
744 return; 744 return;
745 } 745 }
746 746
747 if (ftype == WLAN_SP_MESH_PEERING_OPEN && 747 if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
748 !rssi_threshold_check(sta, sdata)) { 748 !rssi_threshold_check(sta, sdata)) {
749 mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n", 749 mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
750 mgmt->sa); 750 mgmt->sa);
751 rcu_read_unlock(); 751 rcu_read_unlock();
752 return; 752 return;
753 } 753 }
754 754
755 if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { 755 if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
756 mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n"); 756 mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
757 rcu_read_unlock(); 757 rcu_read_unlock();
758 return; 758 return;
759 } 759 }
760 760
761 if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) { 761 if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
762 rcu_read_unlock(); 762 rcu_read_unlock();
763 return; 763 return;
764 } 764 }
765 765
766 /* Now we will figure out the appropriate event... */ 766 /* Now we will figure out the appropriate event... */
767 event = PLINK_UNDEFINED; 767 event = PLINK_UNDEFINED;
768 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 768 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
769 !mesh_matches_local(sdata, &elems)) { 769 !mesh_matches_local(sdata, &elems)) {
770 matches_local = false; 770 matches_local = false;
771 switch (ftype) { 771 switch (ftype) {
772 case WLAN_SP_MESH_PEERING_OPEN: 772 case WLAN_SP_MESH_PEERING_OPEN:
773 event = OPN_RJCT; 773 event = OPN_RJCT;
774 break; 774 break;
775 case WLAN_SP_MESH_PEERING_CONFIRM: 775 case WLAN_SP_MESH_PEERING_CONFIRM:
776 event = CNF_RJCT; 776 event = CNF_RJCT;
777 break; 777 break;
778 default: 778 default:
779 break; 779 break;
780 } 780 }
781 } 781 }
782 782
783 if (!sta && !matches_local) { 783 if (!sta && !matches_local) {
784 rcu_read_unlock(); 784 rcu_read_unlock();
785 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 785 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
786 llid = 0; 786 llid = 0;
787 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 787 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
788 mgmt->sa, llid, plid, reason); 788 mgmt->sa, llid, plid, reason);
789 return; 789 return;
790 } else if (!sta) { 790 } else if (!sta) {
791 /* ftype == WLAN_SP_MESH_PEERING_OPEN */ 791 /* ftype == WLAN_SP_MESH_PEERING_OPEN */
792 if (!mesh_plink_free_count(sdata)) { 792 if (!mesh_plink_free_count(sdata)) {
793 mpl_dbg(sdata, "Mesh plink error: no more free plinks\n"); 793 mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
794 rcu_read_unlock(); 794 rcu_read_unlock();
795 return; 795 return;
796 } 796 }
797 event = OPN_ACPT; 797 event = OPN_ACPT;
798 } else if (matches_local) { 798 } else if (matches_local) {
799 switch (ftype) { 799 switch (ftype) {
800 case WLAN_SP_MESH_PEERING_OPEN: 800 case WLAN_SP_MESH_PEERING_OPEN:
801 if (!mesh_plink_free_count(sdata) || 801 if (!mesh_plink_free_count(sdata) ||
802 (sta->plid && sta->plid != plid)) 802 (sta->plid && sta->plid != plid))
803 event = OPN_IGNR; 803 event = OPN_IGNR;
804 else 804 else
805 event = OPN_ACPT; 805 event = OPN_ACPT;
806 break; 806 break;
807 case WLAN_SP_MESH_PEERING_CONFIRM: 807 case WLAN_SP_MESH_PEERING_CONFIRM:
808 if (!mesh_plink_free_count(sdata) || 808 if (!mesh_plink_free_count(sdata) ||
809 (sta->llid != llid || sta->plid != plid)) 809 (sta->llid != llid || sta->plid != plid))
810 event = CNF_IGNR; 810 event = CNF_IGNR;
811 else 811 else
812 event = CNF_ACPT; 812 event = CNF_ACPT;
813 break; 813 break;
814 case WLAN_SP_MESH_PEERING_CLOSE: 814 case WLAN_SP_MESH_PEERING_CLOSE:
815 if (sta->plink_state == NL80211_PLINK_ESTAB) 815 if (sta->plink_state == NL80211_PLINK_ESTAB)
816 /* Do not check for llid or plid. This does not 816 /* Do not check for llid or plid. This does not
817 * follow the standard but since multiple plinks 817 * follow the standard but since multiple plinks
818 * per sta are not supported, it is necessary in 818 * per sta are not supported, it is necessary in
819 * order to avoid a livelock when MP A sees an 819 * order to avoid a livelock when MP A sees an
820 * establish peer link to MP B but MP B does not 820 * establish peer link to MP B but MP B does not
821 * see it. This can be caused by a timeout in 821 * see it. This can be caused by a timeout in
822 * B's peer link establishment or B beign 822 * B's peer link establishment or B beign
823 * restarted. 823 * restarted.
824 */ 824 */
825 event = CLS_ACPT; 825 event = CLS_ACPT;
826 else if (sta->plid != plid) 826 else if (sta->plid != plid)
827 event = CLS_IGNR; 827 event = CLS_IGNR;
828 else if (ie_len == 7 && sta->llid != llid) 828 else if (ie_len == 8 && sta->llid != llid)
829 event = CLS_IGNR; 829 event = CLS_IGNR;
830 else 830 else
831 event = CLS_ACPT; 831 event = CLS_ACPT;
832 break; 832 break;
833 default: 833 default:
834 mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n"); 834 mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
835 rcu_read_unlock(); 835 rcu_read_unlock();
836 return; 836 return;
837 } 837 }
838 } 838 }
839 839
840 if (event == OPN_ACPT) { 840 if (event == OPN_ACPT) {
841 rcu_read_unlock(); 841 rcu_read_unlock();
842 /* allocate sta entry if necessary and update info */ 842 /* allocate sta entry if necessary and update info */
843 sta = mesh_sta_info_get(sdata, mgmt->sa, &elems); 843 sta = mesh_sta_info_get(sdata, mgmt->sa, &elems);
844 if (!sta) { 844 if (!sta) {
845 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n"); 845 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
846 rcu_read_unlock(); 846 rcu_read_unlock();
847 return; 847 return;
848 } 848 }
849 } 849 }
850 850
851 mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa, 851 mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa,
852 mplstates[sta->plink_state], mplevents[event]); 852 mplstates[sta->plink_state], mplevents[event]);
853 reason = 0; 853 reason = 0;
854 spin_lock_bh(&sta->lock); 854 spin_lock_bh(&sta->lock);
855 switch (sta->plink_state) { 855 switch (sta->plink_state) {
856 /* spin_unlock as soon as state is updated at each case */ 856 /* spin_unlock as soon as state is updated at each case */
857 case NL80211_PLINK_LISTEN: 857 case NL80211_PLINK_LISTEN:
858 switch (event) { 858 switch (event) {
859 case CLS_ACPT: 859 case CLS_ACPT:
860 mesh_plink_fsm_restart(sta); 860 mesh_plink_fsm_restart(sta);
861 spin_unlock_bh(&sta->lock); 861 spin_unlock_bh(&sta->lock);
862 break; 862 break;
863 case OPN_ACPT: 863 case OPN_ACPT:
864 sta->plink_state = NL80211_PLINK_OPN_RCVD; 864 sta->plink_state = NL80211_PLINK_OPN_RCVD;
865 sta->plid = plid; 865 sta->plid = plid;
866 get_random_bytes(&llid, 2); 866 get_random_bytes(&llid, 2);
867 sta->llid = llid; 867 sta->llid = llid;
868 mesh_plink_timer_set(sta, 868 mesh_plink_timer_set(sta,
869 mshcfg->dot11MeshRetryTimeout); 869 mshcfg->dot11MeshRetryTimeout);
870 870
871 /* set the non-peer mode to active during peering */ 871 /* set the non-peer mode to active during peering */
872 changed |= ieee80211_mps_local_status_update(sdata); 872 changed |= ieee80211_mps_local_status_update(sdata);
873 873
874 spin_unlock_bh(&sta->lock); 874 spin_unlock_bh(&sta->lock);
875 mesh_plink_frame_tx(sdata, 875 mesh_plink_frame_tx(sdata,
876 WLAN_SP_MESH_PEERING_OPEN, 876 WLAN_SP_MESH_PEERING_OPEN,
877 sta->sta.addr, llid, 0, 0); 877 sta->sta.addr, llid, 0, 0);
878 mesh_plink_frame_tx(sdata, 878 mesh_plink_frame_tx(sdata,
879 WLAN_SP_MESH_PEERING_CONFIRM, 879 WLAN_SP_MESH_PEERING_CONFIRM,
880 sta->sta.addr, llid, plid, 0); 880 sta->sta.addr, llid, plid, 0);
881 break; 881 break;
882 default: 882 default:
883 spin_unlock_bh(&sta->lock); 883 spin_unlock_bh(&sta->lock);
884 break; 884 break;
885 } 885 }
886 break; 886 break;
887 887
888 case NL80211_PLINK_OPN_SNT: 888 case NL80211_PLINK_OPN_SNT:
889 switch (event) { 889 switch (event) {
890 case OPN_RJCT: 890 case OPN_RJCT:
891 case CNF_RJCT: 891 case CNF_RJCT:
892 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 892 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
893 case CLS_ACPT: 893 case CLS_ACPT:
894 if (!reason) 894 if (!reason)
895 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 895 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
896 sta->reason = reason; 896 sta->reason = reason;
897 sta->plink_state = NL80211_PLINK_HOLDING; 897 sta->plink_state = NL80211_PLINK_HOLDING;
898 if (!mod_plink_timer(sta, 898 if (!mod_plink_timer(sta,
899 mshcfg->dot11MeshHoldingTimeout)) 899 mshcfg->dot11MeshHoldingTimeout))
900 sta->ignore_plink_timer = true; 900 sta->ignore_plink_timer = true;
901 901
902 llid = sta->llid; 902 llid = sta->llid;
903 spin_unlock_bh(&sta->lock); 903 spin_unlock_bh(&sta->lock);
904 mesh_plink_frame_tx(sdata, 904 mesh_plink_frame_tx(sdata,
905 WLAN_SP_MESH_PEERING_CLOSE, 905 WLAN_SP_MESH_PEERING_CLOSE,
906 sta->sta.addr, llid, plid, reason); 906 sta->sta.addr, llid, plid, reason);
907 break; 907 break;
908 case OPN_ACPT: 908 case OPN_ACPT:
909 /* retry timer is left untouched */ 909 /* retry timer is left untouched */
910 sta->plink_state = NL80211_PLINK_OPN_RCVD; 910 sta->plink_state = NL80211_PLINK_OPN_RCVD;
911 sta->plid = plid; 911 sta->plid = plid;
912 llid = sta->llid; 912 llid = sta->llid;
913 spin_unlock_bh(&sta->lock); 913 spin_unlock_bh(&sta->lock);
914 mesh_plink_frame_tx(sdata, 914 mesh_plink_frame_tx(sdata,
915 WLAN_SP_MESH_PEERING_CONFIRM, 915 WLAN_SP_MESH_PEERING_CONFIRM,
916 sta->sta.addr, llid, plid, 0); 916 sta->sta.addr, llid, plid, 0);
917 break; 917 break;
918 case CNF_ACPT: 918 case CNF_ACPT:
919 sta->plink_state = NL80211_PLINK_CNF_RCVD; 919 sta->plink_state = NL80211_PLINK_CNF_RCVD;
920 if (!mod_plink_timer(sta, 920 if (!mod_plink_timer(sta,
921 mshcfg->dot11MeshConfirmTimeout)) 921 mshcfg->dot11MeshConfirmTimeout))
922 sta->ignore_plink_timer = true; 922 sta->ignore_plink_timer = true;
923 923
924 spin_unlock_bh(&sta->lock); 924 spin_unlock_bh(&sta->lock);
925 break; 925 break;
926 default: 926 default:
927 spin_unlock_bh(&sta->lock); 927 spin_unlock_bh(&sta->lock);
928 break; 928 break;
929 } 929 }
930 break; 930 break;
931 931
932 case NL80211_PLINK_OPN_RCVD: 932 case NL80211_PLINK_OPN_RCVD:
933 switch (event) { 933 switch (event) {
934 case OPN_RJCT: 934 case OPN_RJCT:
935 case CNF_RJCT: 935 case CNF_RJCT:
936 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 936 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
937 case CLS_ACPT: 937 case CLS_ACPT:
938 if (!reason) 938 if (!reason)
939 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 939 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
940 sta->reason = reason; 940 sta->reason = reason;
941 sta->plink_state = NL80211_PLINK_HOLDING; 941 sta->plink_state = NL80211_PLINK_HOLDING;
942 if (!mod_plink_timer(sta, 942 if (!mod_plink_timer(sta,
943 mshcfg->dot11MeshHoldingTimeout)) 943 mshcfg->dot11MeshHoldingTimeout))
944 sta->ignore_plink_timer = true; 944 sta->ignore_plink_timer = true;
945 945
946 llid = sta->llid; 946 llid = sta->llid;
947 spin_unlock_bh(&sta->lock); 947 spin_unlock_bh(&sta->lock);
948 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 948 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
949 sta->sta.addr, llid, plid, reason); 949 sta->sta.addr, llid, plid, reason);
950 break; 950 break;
951 case OPN_ACPT: 951 case OPN_ACPT:
952 llid = sta->llid; 952 llid = sta->llid;
953 spin_unlock_bh(&sta->lock); 953 spin_unlock_bh(&sta->lock);
954 mesh_plink_frame_tx(sdata, 954 mesh_plink_frame_tx(sdata,
955 WLAN_SP_MESH_PEERING_CONFIRM, 955 WLAN_SP_MESH_PEERING_CONFIRM,
956 sta->sta.addr, llid, plid, 0); 956 sta->sta.addr, llid, plid, 0);
957 break; 957 break;
958 case CNF_ACPT: 958 case CNF_ACPT:
959 del_timer(&sta->plink_timer); 959 del_timer(&sta->plink_timer);
960 sta->plink_state = NL80211_PLINK_ESTAB; 960 sta->plink_state = NL80211_PLINK_ESTAB;
961 spin_unlock_bh(&sta->lock); 961 spin_unlock_bh(&sta->lock);
962 changed |= mesh_plink_inc_estab_count(sdata); 962 changed |= mesh_plink_inc_estab_count(sdata);
963 changed |= mesh_set_ht_prot_mode(sdata); 963 changed |= mesh_set_ht_prot_mode(sdata);
964 changed |= mesh_set_short_slot_time(sdata); 964 changed |= mesh_set_short_slot_time(sdata);
965 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 965 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
966 sta->sta.addr); 966 sta->sta.addr);
967 ieee80211_mps_sta_status_update(sta); 967 ieee80211_mps_sta_status_update(sta);
968 changed |= ieee80211_mps_set_sta_local_pm(sta, 968 changed |= ieee80211_mps_set_sta_local_pm(sta,
969 mshcfg->power_mode); 969 mshcfg->power_mode);
970 break; 970 break;
971 default: 971 default:
972 spin_unlock_bh(&sta->lock); 972 spin_unlock_bh(&sta->lock);
973 break; 973 break;
974 } 974 }
975 break; 975 break;
976 976
977 case NL80211_PLINK_CNF_RCVD: 977 case NL80211_PLINK_CNF_RCVD:
978 switch (event) { 978 switch (event) {
979 case OPN_RJCT: 979 case OPN_RJCT:
980 case CNF_RJCT: 980 case CNF_RJCT:
981 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 981 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
982 case CLS_ACPT: 982 case CLS_ACPT:
983 if (!reason) 983 if (!reason)
984 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 984 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
985 sta->reason = reason; 985 sta->reason = reason;
986 sta->plink_state = NL80211_PLINK_HOLDING; 986 sta->plink_state = NL80211_PLINK_HOLDING;
987 if (!mod_plink_timer(sta, 987 if (!mod_plink_timer(sta,
988 mshcfg->dot11MeshHoldingTimeout)) 988 mshcfg->dot11MeshHoldingTimeout))
989 sta->ignore_plink_timer = true; 989 sta->ignore_plink_timer = true;
990 990
991 llid = sta->llid; 991 llid = sta->llid;
992 spin_unlock_bh(&sta->lock); 992 spin_unlock_bh(&sta->lock);
993 mesh_plink_frame_tx(sdata, 993 mesh_plink_frame_tx(sdata,
994 WLAN_SP_MESH_PEERING_CLOSE, 994 WLAN_SP_MESH_PEERING_CLOSE,
995 sta->sta.addr, llid, plid, reason); 995 sta->sta.addr, llid, plid, reason);
996 break; 996 break;
997 case OPN_ACPT: 997 case OPN_ACPT:
998 del_timer(&sta->plink_timer); 998 del_timer(&sta->plink_timer);
999 sta->plink_state = NL80211_PLINK_ESTAB; 999 sta->plink_state = NL80211_PLINK_ESTAB;
1000 spin_unlock_bh(&sta->lock); 1000 spin_unlock_bh(&sta->lock);
1001 changed |= mesh_plink_inc_estab_count(sdata); 1001 changed |= mesh_plink_inc_estab_count(sdata);
1002 changed |= mesh_set_ht_prot_mode(sdata); 1002 changed |= mesh_set_ht_prot_mode(sdata);
1003 changed |= mesh_set_short_slot_time(sdata); 1003 changed |= mesh_set_short_slot_time(sdata);
1004 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 1004 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
1005 sta->sta.addr); 1005 sta->sta.addr);
1006 mesh_plink_frame_tx(sdata, 1006 mesh_plink_frame_tx(sdata,
1007 WLAN_SP_MESH_PEERING_CONFIRM, 1007 WLAN_SP_MESH_PEERING_CONFIRM,
1008 sta->sta.addr, llid, plid, 0); 1008 sta->sta.addr, llid, plid, 0);
1009 ieee80211_mps_sta_status_update(sta); 1009 ieee80211_mps_sta_status_update(sta);
1010 changed |= ieee80211_mps_set_sta_local_pm(sta, 1010 changed |= ieee80211_mps_set_sta_local_pm(sta,
1011 mshcfg->power_mode); 1011 mshcfg->power_mode);
1012 break; 1012 break;
1013 default: 1013 default:
1014 spin_unlock_bh(&sta->lock); 1014 spin_unlock_bh(&sta->lock);
1015 break; 1015 break;
1016 } 1016 }
1017 break; 1017 break;
1018 1018
1019 case NL80211_PLINK_ESTAB: 1019 case NL80211_PLINK_ESTAB:
1020 switch (event) { 1020 switch (event) {
1021 case CLS_ACPT: 1021 case CLS_ACPT:
1022 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 1022 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
1023 sta->reason = reason; 1023 sta->reason = reason;
1024 changed |= __mesh_plink_deactivate(sta); 1024 changed |= __mesh_plink_deactivate(sta);
1025 sta->plink_state = NL80211_PLINK_HOLDING; 1025 sta->plink_state = NL80211_PLINK_HOLDING;
1026 llid = sta->llid; 1026 llid = sta->llid;
1027 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); 1027 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
1028 spin_unlock_bh(&sta->lock); 1028 spin_unlock_bh(&sta->lock);
1029 changed |= mesh_set_ht_prot_mode(sdata); 1029 changed |= mesh_set_ht_prot_mode(sdata);
1030 changed |= mesh_set_short_slot_time(sdata); 1030 changed |= mesh_set_short_slot_time(sdata);
1031 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 1031 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
1032 sta->sta.addr, llid, plid, reason); 1032 sta->sta.addr, llid, plid, reason);
1033 break; 1033 break;
1034 case OPN_ACPT: 1034 case OPN_ACPT:
1035 llid = sta->llid; 1035 llid = sta->llid;
1036 spin_unlock_bh(&sta->lock); 1036 spin_unlock_bh(&sta->lock);
1037 mesh_plink_frame_tx(sdata, 1037 mesh_plink_frame_tx(sdata,
1038 WLAN_SP_MESH_PEERING_CONFIRM, 1038 WLAN_SP_MESH_PEERING_CONFIRM,
1039 sta->sta.addr, llid, plid, 0); 1039 sta->sta.addr, llid, plid, 0);
1040 break; 1040 break;
1041 default: 1041 default:
1042 spin_unlock_bh(&sta->lock); 1042 spin_unlock_bh(&sta->lock);
1043 break; 1043 break;
1044 } 1044 }
1045 break; 1045 break;
1046 case NL80211_PLINK_HOLDING: 1046 case NL80211_PLINK_HOLDING:
1047 switch (event) { 1047 switch (event) {
1048 case CLS_ACPT: 1048 case CLS_ACPT:
1049 if (del_timer(&sta->plink_timer)) 1049 if (del_timer(&sta->plink_timer))
1050 sta->ignore_plink_timer = 1; 1050 sta->ignore_plink_timer = 1;
1051 mesh_plink_fsm_restart(sta); 1051 mesh_plink_fsm_restart(sta);
1052 spin_unlock_bh(&sta->lock); 1052 spin_unlock_bh(&sta->lock);
1053 break; 1053 break;
1054 case OPN_ACPT: 1054 case OPN_ACPT:
1055 case CNF_ACPT: 1055 case CNF_ACPT:
1056 case OPN_RJCT: 1056 case OPN_RJCT:
1057 case CNF_RJCT: 1057 case CNF_RJCT:
1058 llid = sta->llid; 1058 llid = sta->llid;
1059 reason = sta->reason; 1059 reason = sta->reason;
1060 spin_unlock_bh(&sta->lock); 1060 spin_unlock_bh(&sta->lock);
1061 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 1061 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
1062 sta->sta.addr, llid, plid, reason); 1062 sta->sta.addr, llid, plid, reason);
1063 break; 1063 break;
1064 default: 1064 default:
1065 spin_unlock_bh(&sta->lock); 1065 spin_unlock_bh(&sta->lock);
1066 } 1066 }
1067 break; 1067 break;
1068 default: 1068 default:
1069 /* should not get here, PLINK_BLOCKED is dealt with at the 1069 /* should not get here, PLINK_BLOCKED is dealt with at the
1070 * beginning of the function 1070 * beginning of the function
1071 */ 1071 */
1072 spin_unlock_bh(&sta->lock); 1072 spin_unlock_bh(&sta->lock);
1073 break; 1073 break;
1074 } 1074 }
1075 1075
1076 rcu_read_unlock(); 1076 rcu_read_unlock();
1077 1077
1078 if (changed) 1078 if (changed)
1079 ieee80211_mbss_info_change_notify(sdata, changed); 1079 ieee80211_mbss_info_change_notify(sdata, changed);
1080 } 1080 }
1081 1081