Blame view
net/mac80211/mesh_plink.c
22.3 KB
c3896d2ca mac80211: mesh pe... |
1 |
/* |
264d9b7d8 mac80211: update ... |
2 |
* Copyright (c) 2008, 2009 open80211s Ltd. |
c3896d2ca mac80211: mesh pe... |
3 4 5 6 7 8 |
* Author: Luis Carlos Cobo <luisca@cozybit.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ |
5a0e3ad6a include cleanup: ... |
9 |
#include <linux/gfp.h> |
902acc789 mac80211: clean u... |
10 11 |
#include <linux/kernel.h> #include <linux/random.h> |
c3896d2ca mac80211: mesh pe... |
12 |
#include "ieee80211_i.h" |
2c8dccc77 mac80211: rename ... |
13 |
#include "rate.h" |
c3896d2ca mac80211: mesh pe... |
14 |
#include "mesh.h" |
c3896d2ca mac80211: mesh pe... |
15 16 17 18 19 20 |
#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG #define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) #else #define mpl_dbg(fmt, args...) do { (void)(0); } while (0) #endif |
8db098507 mac80211: update ... |
21 22 |
#define PLINK_GET_LLID(p) (p + 2) #define PLINK_GET_PLID(p) (p + 4) |
c3896d2ca mac80211: mesh pe... |
23 24 25 |
#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ jiffies + HZ * t / 1000)) |
472dbc45d mac80211: split o... |
26 27 28 29 30 |
#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries) #define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout) #define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout) #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) |
c3896d2ca mac80211: mesh pe... |
31 |
|
c3896d2ca mac80211: mesh pe... |
32 33 34 35 36 37 38 39 40 41 42 |
enum plink_event { PLINK_UNDEFINED, OPN_ACPT, OPN_RJCT, OPN_IGNR, CNF_ACPT, CNF_RJCT, CNF_IGNR, CLS_ACPT, CLS_IGNR }; |
ba4a14e10 mac80211: notify ... |
43 44 45 |
static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, enum ieee80211_self_protected_actioncode action, u8 *da, __le16 llid, __le16 plid, __le16 reason); |
c3896d2ca mac80211: mesh pe... |
46 47 48 |
static inline void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) { |
472dbc45d mac80211: split o... |
49 |
atomic_inc(&sdata->u.mesh.mshstats.estab_plinks); |
d0709a651 mac80211: RCU-ify... |
50 |
mesh_accept_plinks_update(sdata); |
c3896d2ca mac80211: mesh pe... |
51 52 53 54 55 |
} static inline void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) { |
472dbc45d mac80211: split o... |
56 |
atomic_dec(&sdata->u.mesh.mshstats.estab_plinks); |
d0709a651 mac80211: RCU-ify... |
57 |
mesh_accept_plinks_update(sdata); |
c3896d2ca mac80211: mesh pe... |
58 59 60 61 62 |
} /** * mesh_plink_fsm_restart - restart a mesh peer link finite state machine * |
23c7a29cd mac80211: fix typ... |
63 |
* @sta: mesh peer link to restart |
c3896d2ca mac80211: mesh pe... |
64 |
* |
07346f81e mac80211: proper ... |
65 |
* Locking: this function must be called holding sta->lock |
c3896d2ca mac80211: mesh pe... |
66 67 68 |
*/ static inline void mesh_plink_fsm_restart(struct sta_info *sta) { |
57cf8043a nl80211: Move pee... |
69 |
sta->plink_state = NL80211_PLINK_LISTEN; |
37659ff8e mac80211: fix mes... |
70 71 |
sta->llid = sta->plid = sta->reason = 0; sta->plink_retries = 0; |
c3896d2ca mac80211: mesh pe... |
72 |
} |
93e5deb1a mac80211: automat... |
73 74 75 76 |
/* * NOTE: This is just an alias for sta_info_alloc(), see notes * on it in the lifecycle management section! */ |
03e4497eb mac80211: fix sta... |
77 |
static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, |
739522baa mac80211: set HT ... |
78 79 |
u8 *hw_addr, u32 rates, struct ieee802_11_elems *elems) |
c3896d2ca mac80211: mesh pe... |
80 |
{ |
d0709a651 mac80211: RCU-ify... |
81 |
struct ieee80211_local *local = sdata->local; |
739522baa mac80211: set HT ... |
82 |
struct ieee80211_supported_band *sband; |
c3896d2ca mac80211: mesh pe... |
83 |
struct sta_info *sta; |
739522baa mac80211: set HT ... |
84 |
sband = local->hw.wiphy->bands[local->oper_channel->band]; |
c3896d2ca mac80211: mesh pe... |
85 |
if (local->num_sta >= MESH_MAX_PLINKS) |
73651ee63 mac80211: split s... |
86 |
return NULL; |
c3896d2ca mac80211: mesh pe... |
87 |
|
34e895075 mac80211: allow s... |
88 |
sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL); |
73651ee63 mac80211: split s... |
89 90 |
if (!sta) return NULL; |
c3896d2ca mac80211: mesh pe... |
91 |
|
d9a7ddb05 mac80211: refacto... |
92 93 94 |
sta_info_move_state(sta, IEEE80211_STA_AUTH); sta_info_move_state(sta, IEEE80211_STA_ASSOC); sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); |
c2c98fdeb mac80211: optimis... |
95 |
set_sta_flag(sta, WLAN_STA_WME); |
d9a7ddb05 mac80211: refacto... |
96 |
|
323ce79a9 mac80211: share s... |
97 |
sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
739522baa mac80211: set HT ... |
98 |
if (elems->ht_cap_elem) |
ef96a8420 mac80211: Support... |
99 100 |
ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, elems->ht_cap_elem, |
739522baa mac80211: set HT ... |
101 |
&sta->sta.ht_cap); |
b973c31a9 mac80211: initial... |
102 |
rate_control_rate_init(sta); |
c3896d2ca mac80211: mesh pe... |
103 104 105 106 107 |
return sta; } /** |
c93701976 mac80211: avoid s... |
108 |
* __mesh_plink_deactivate - deactivate mesh peer link |
c3896d2ca mac80211: mesh pe... |
109 110 111 112 113 |
* * @sta: mesh peer link to deactivate * * All mesh paths with this peer as next hop will be flushed * |
07346f81e mac80211: proper ... |
114 |
* Locking: the caller must hold sta->lock |
c3896d2ca mac80211: mesh pe... |
115 |
*/ |
c93701976 mac80211: avoid s... |
116 |
static bool __mesh_plink_deactivate(struct sta_info *sta) |
c3896d2ca mac80211: mesh pe... |
117 |
{ |
d0709a651 mac80211: RCU-ify... |
118 |
struct ieee80211_sub_if_data *sdata = sta->sdata; |
c93701976 mac80211: avoid s... |
119 |
bool deactivated = false; |
d0709a651 mac80211: RCU-ify... |
120 |
|
57cf8043a nl80211: Move pee... |
121 |
if (sta->plink_state == NL80211_PLINK_ESTAB) { |
c3896d2ca mac80211: mesh pe... |
122 |
mesh_plink_dec_estab_count(sdata); |
c93701976 mac80211: avoid s... |
123 124 |
deactivated = true; } |
57cf8043a nl80211: Move pee... |
125 |
sta->plink_state = NL80211_PLINK_BLOCKED; |
c3896d2ca mac80211: mesh pe... |
126 |
mesh_path_flush_by_nexthop(sta); |
c93701976 mac80211: avoid s... |
127 128 |
return deactivated; |
c3896d2ca mac80211: mesh pe... |
129 |
} |
902acc789 mac80211: clean u... |
130 |
/** |
c93701976 mac80211: avoid s... |
131 |
* mesh_plink_deactivate - deactivate mesh peer link |
902acc789 mac80211: clean u... |
132 133 134 135 136 137 138 |
* * @sta: mesh peer link to deactivate * * All mesh paths with this peer as next hop will be flushed */ void mesh_plink_deactivate(struct sta_info *sta) { |
c93701976 mac80211: avoid s... |
139 140 |
struct ieee80211_sub_if_data *sdata = sta->sdata; bool deactivated; |
07346f81e mac80211: proper ... |
141 |
spin_lock_bh(&sta->lock); |
c93701976 mac80211: avoid s... |
142 |
deactivated = __mesh_plink_deactivate(sta); |
ba4a14e10 mac80211: notify ... |
143 144 145 146 |
sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED); mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, sta->sta.addr, sta->llid, sta->plid, sta->reason); |
07346f81e mac80211: proper ... |
147 |
spin_unlock_bh(&sta->lock); |
c93701976 mac80211: avoid s... |
148 149 150 |
if (deactivated) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
902acc789 mac80211: clean u... |
151 |
} |
f698d856f replace net_devic... |
152 |
static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, |
54ef656b0 mac80211: update ... |
153 154 |
enum ieee80211_self_protected_actioncode action, u8 *da, __le16 llid, __le16 plid, __le16 reason) { |
f698d856f replace net_devic... |
155 |
struct ieee80211_local *local = sdata->local; |
3b69a9c5f mac80211: comment... |
156 |
struct sk_buff *skb; |
c3896d2ca mac80211: mesh pe... |
157 158 |
struct ieee80211_mgmt *mgmt; bool include_plid = false; |
8db098507 mac80211: update ... |
159 |
u16 peering_proto = 0; |
3b69a9c5f mac80211: comment... |
160 161 162 163 164 165 166 167 168 169 170 171 |
u8 *pos, ie_len = 4; int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) + sizeof(mgmt->u.action.u.self_prot); skb = dev_alloc_skb(local->hw.extra_tx_headroom + hdr_len + 2 + /* capability info */ 2 + /* AID */ 2 + 8 + /* supported rates */ 2 + (IEEE80211_MAX_SUPP_RATES - 8) + 2 + sdata->u.mesh.mesh_id_len + 2 + sizeof(struct ieee80211_meshconf_ie) + |
176f36086 mac80211: add HT ... |
172 173 |
2 + sizeof(struct ieee80211_ht_cap) + 2 + sizeof(struct ieee80211_ht_info) + |
3b69a9c5f mac80211: comment... |
174 175 |
2 + 8 + /* peering IE */ sdata->u.mesh.ie_len); |
c3896d2ca mac80211: mesh pe... |
176 177 178 |
if (!skb) return -1; skb_reserve(skb, local->hw.extra_tx_headroom); |
3b69a9c5f mac80211: comment... |
179 180 |
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); memset(mgmt, 0, hdr_len); |
e7827a703 mac80211: remove ... |
181 182 |
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); |
c3896d2ca mac80211: mesh pe... |
183 |
memcpy(mgmt->da, da, ETH_ALEN); |
47846c9b0 mac80211: reduce ... |
184 |
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
915b5c50f open80211s: Stop ... |
185 |
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
8db098507 mac80211: update ... |
186 187 |
mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED; mgmt->u.action.u.self_prot.action_code = action; |
c3896d2ca mac80211: mesh pe... |
188 |
|
8db098507 mac80211: update ... |
189 190 191 192 |
if (action != WLAN_SP_MESH_PEERING_CLOSE) { /* capability info */ pos = skb_put(skb, 2); memset(pos, 0, 2); |
54ef656b0 mac80211: update ... |
193 |
if (action == WLAN_SP_MESH_PEERING_CONFIRM) { |
8db098507 mac80211: update ... |
194 195 |
/* AID */ pos = skb_put(skb, 2); |
77fa76bb7 mac80211: set the... |
196 |
memcpy(pos + 2, &plid, 2); |
c3896d2ca mac80211: mesh pe... |
197 |
} |
768db3438 mac80211: standar... |
198 199 |
if (ieee80211_add_srates_ie(&sdata->vif, skb) || ieee80211_add_ext_srates_ie(&sdata->vif, skb) || |
082ebb0c2 mac80211: fix mes... |
200 201 202 203 |
mesh_add_rsn_ie(skb, sdata) || mesh_add_meshid_ie(skb, sdata) || mesh_add_meshconf_ie(skb, sdata)) return -1; |
8db098507 mac80211: update ... |
204 205 206 |
} else { /* WLAN_SP_MESH_PEERING_CLOSE */ if (mesh_add_meshid_ie(skb, sdata)) return -1; |
c3896d2ca mac80211: mesh pe... |
207 |
} |
8db098507 mac80211: update ... |
208 |
/* Add Mesh Peering Management element */ |
c3896d2ca mac80211: mesh pe... |
209 |
switch (action) { |
54ef656b0 mac80211: update ... |
210 |
case WLAN_SP_MESH_PEERING_OPEN: |
c3896d2ca mac80211: mesh pe... |
211 |
break; |
54ef656b0 mac80211: update ... |
212 |
case WLAN_SP_MESH_PEERING_CONFIRM: |
8db098507 mac80211: update ... |
213 |
ie_len += 2; |
c3896d2ca mac80211: mesh pe... |
214 215 |
include_plid = true; break; |
54ef656b0 mac80211: update ... |
216 |
case WLAN_SP_MESH_PEERING_CLOSE: |
8db098507 mac80211: update ... |
217 218 |
if (plid) { ie_len += 2; |
c3896d2ca mac80211: mesh pe... |
219 220 |
include_plid = true; } |
8db098507 mac80211: update ... |
221 |
ie_len += 2; /* reason code */ |
c3896d2ca mac80211: mesh pe... |
222 |
break; |
8db098507 mac80211: update ... |
223 224 |
default: return -EINVAL; |
c3896d2ca mac80211: mesh pe... |
225 |
} |
8db098507 mac80211: update ... |
226 227 |
if (WARN_ON(skb_tailroom(skb) < 2 + ie_len)) return -ENOMEM; |
c3896d2ca mac80211: mesh pe... |
228 |
pos = skb_put(skb, 2 + ie_len); |
8db098507 mac80211: update ... |
229 |
*pos++ = WLAN_EID_PEER_MGMT; |
c3896d2ca mac80211: mesh pe... |
230 |
*pos++ = ie_len; |
8db098507 mac80211: update ... |
231 232 |
memcpy(pos, &peering_proto, 2); pos += 2; |
c3896d2ca mac80211: mesh pe... |
233 |
memcpy(pos, &llid, 2); |
8db098507 mac80211: update ... |
234 |
pos += 2; |
c3896d2ca mac80211: mesh pe... |
235 |
if (include_plid) { |
c3896d2ca mac80211: mesh pe... |
236 |
memcpy(pos, &plid, 2); |
8db098507 mac80211: update ... |
237 |
pos += 2; |
c3896d2ca mac80211: mesh pe... |
238 |
} |
54ef656b0 mac80211: update ... |
239 |
if (action == WLAN_SP_MESH_PEERING_CLOSE) { |
c3896d2ca mac80211: mesh pe... |
240 |
memcpy(pos, &reason, 2); |
8db098507 mac80211: update ... |
241 |
pos += 2; |
c3896d2ca mac80211: mesh pe... |
242 |
} |
176f36086 mac80211: add HT ... |
243 244 245 246 247 248 |
if (action != WLAN_SP_MESH_PEERING_CLOSE) { if (mesh_add_ht_cap_ie(skb, sdata) || mesh_add_ht_info_ie(skb, sdata)) return -1; } |
8db098507 mac80211: update ... |
249 250 |
if (mesh_add_vendor_ies(skb, sdata)) return -1; |
c3896d2ca mac80211: mesh pe... |
251 |
|
62ae67be3 mac80211: remove ... |
252 |
ieee80211_tx_skb(sdata, skb); |
c3896d2ca mac80211: mesh pe... |
253 254 |
return 0; } |
1570ca592 mac80211: send no... |
255 256 257 |
void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata, struct ieee802_11_elems *elems) |
c3896d2ca mac80211: mesh pe... |
258 |
{ |
f698d856f replace net_devic... |
259 |
struct ieee80211_local *local = sdata->local; |
c3896d2ca mac80211: mesh pe... |
260 |
struct sta_info *sta; |
d0709a651 mac80211: RCU-ify... |
261 |
rcu_read_lock(); |
abe60632f mac80211: make st... |
262 |
sta = sta_info_get(sdata, hw_addr); |
c3896d2ca mac80211: mesh pe... |
263 |
if (!sta) { |
34e895075 mac80211: allow s... |
264 |
rcu_read_unlock(); |
1570ca592 mac80211: send no... |
265 266 |
/* Userspace handles peer allocation when security is enabled * */ |
b130e5cec nl80211: Introduc... |
267 |
if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) |
1570ca592 mac80211: send no... |
268 269 270 271 |
cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, elems->ie_start, elems->total_len, GFP_KERNEL); else |
739522baa mac80211: set HT ... |
272 |
sta = mesh_plink_alloc(sdata, hw_addr, rates, elems); |
34e895075 mac80211: allow s... |
273 |
if (!sta) |
73651ee63 mac80211: split s... |
274 |
return; |
34e895075 mac80211: allow s... |
275 |
if (sta_info_insert_rcu(sta)) { |
d0709a651 mac80211: RCU-ify... |
276 |
rcu_read_unlock(); |
c3896d2ca mac80211: mesh pe... |
277 |
return; |
d0709a651 mac80211: RCU-ify... |
278 |
} |
c3896d2ca mac80211: mesh pe... |
279 280 281 |
} sta->last_rx = jiffies; |
323ce79a9 mac80211: share s... |
282 |
sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
1570ca592 mac80211: send no... |
283 |
if (mesh_peer_accepts_plinks(elems) && |
57cf8043a nl80211: Move pee... |
284 |
sta->plink_state == NL80211_PLINK_LISTEN && |
472dbc45d mac80211: split o... |
285 286 |
sdata->u.mesh.accepting_plinks && sdata->u.mesh.mshcfg.auto_open_plinks) |
c3896d2ca mac80211: mesh pe... |
287 |
mesh_plink_open(sta); |
d0709a651 mac80211: RCU-ify... |
288 |
rcu_read_unlock(); |
c3896d2ca mac80211: mesh pe... |
289 290 291 292 293 294 |
} static void mesh_plink_timer(unsigned long data) { struct sta_info *sta; __le16 llid, plid, reason; |
c3896d2ca mac80211: mesh pe... |
295 |
struct ieee80211_sub_if_data *sdata; |
c3896d2ca mac80211: mesh pe... |
296 |
|
d0709a651 mac80211: RCU-ify... |
297 298 299 300 301 |
/* * This STA is valid because sta_info_destroy() will * del_timer_sync() this timer after having made sure * it cannot be readded (by deleting the plink.) */ |
c3896d2ca mac80211: mesh pe... |
302 |
sta = (struct sta_info *) data; |
5bb644a0f mac80211: cancel/... |
303 304 305 306 |
if (sta->sdata->local->quiescing) { sta->plink_timer_was_running = true; return; } |
07346f81e mac80211: proper ... |
307 |
spin_lock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
308 309 |
if (sta->ignore_plink_timer) { sta->ignore_plink_timer = false; |
07346f81e mac80211: proper ... |
310 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
311 312 |
return; } |
0c68ae260 mac80211: convert... |
313 314 315 |
mpl_dbg("Mesh plink timer for %pM fired on state %d ", sta->sta.addr, sta->plink_state); |
c3896d2ca mac80211: mesh pe... |
316 317 318 |
reason = 0; llid = sta->llid; plid = sta->plid; |
d0709a651 mac80211: RCU-ify... |
319 |
sdata = sta->sdata; |
c3896d2ca mac80211: mesh pe... |
320 321 |
switch (sta->plink_state) { |
57cf8043a nl80211: Move pee... |
322 323 |
case NL80211_PLINK_OPN_RCVD: case NL80211_PLINK_OPN_SNT: |
c3896d2ca mac80211: mesh pe... |
324 325 326 |
/* retry timer */ if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { u32 rand; |
0c68ae260 mac80211: convert... |
327 328 329 330 |
mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d ", sta->sta.addr, sta->plink_retries, sta->plink_timeout); |
c3896d2ca mac80211: mesh pe... |
331 332 333 334 |
get_random_bytes(&rand, sizeof(u32)); sta->plink_timeout = sta->plink_timeout + rand % sta->plink_timeout; ++sta->plink_retries; |
d0709a651 mac80211: RCU-ify... |
335 |
mod_plink_timer(sta, sta->plink_timeout); |
07346f81e mac80211: proper ... |
336 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
337 338 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, sta->sta.addr, llid, 0, 0); |
c3896d2ca mac80211: mesh pe... |
339 340 |
break; } |
54ef656b0 mac80211: update ... |
341 |
reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES); |
c3896d2ca mac80211: mesh pe... |
342 |
/* fall through on else */ |
57cf8043a nl80211: Move pee... |
343 |
case NL80211_PLINK_CNF_RCVD: |
c3896d2ca mac80211: mesh pe... |
344 345 |
/* confirm timer */ if (!reason) |
54ef656b0 mac80211: update ... |
346 |
reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT); |
57cf8043a nl80211: Move pee... |
347 |
sta->plink_state = NL80211_PLINK_HOLDING; |
d0709a651 mac80211: RCU-ify... |
348 |
mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
07346f81e mac80211: proper ... |
349 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
350 351 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, sta->sta.addr, llid, plid, reason); |
c3896d2ca mac80211: mesh pe... |
352 |
break; |
57cf8043a nl80211: Move pee... |
353 |
case NL80211_PLINK_HOLDING: |
c3896d2ca mac80211: mesh pe... |
354 |
/* holding timer */ |
d0709a651 mac80211: RCU-ify... |
355 |
del_timer(&sta->plink_timer); |
c3896d2ca mac80211: mesh pe... |
356 |
mesh_plink_fsm_restart(sta); |
07346f81e mac80211: proper ... |
357 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
358 359 |
break; default: |
07346f81e mac80211: proper ... |
360 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
361 362 |
break; } |
c3896d2ca mac80211: mesh pe... |
363 |
} |
5bb644a0f mac80211: cancel/... |
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
#ifdef CONFIG_PM void mesh_plink_quiesce(struct sta_info *sta) { if (del_timer_sync(&sta->plink_timer)) sta->plink_timer_was_running = true; } void mesh_plink_restart(struct sta_info *sta) { if (sta->plink_timer_was_running) { add_timer(&sta->plink_timer); sta->plink_timer_was_running = false; } } #endif |
c3896d2ca mac80211: mesh pe... |
379 380 381 382 383 384 |
static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) { sta->plink_timer.expires = jiffies + (HZ * timeout / 1000); sta->plink_timer.data = (unsigned long) sta; sta->plink_timer.function = mesh_plink_timer; sta->plink_timeout = timeout; |
c3896d2ca mac80211: mesh pe... |
385 386 387 388 389 390 |
add_timer(&sta->plink_timer); } int mesh_plink_open(struct sta_info *sta) { __le16 llid; |
d0709a651 mac80211: RCU-ify... |
391 |
struct ieee80211_sub_if_data *sdata = sta->sdata; |
c3896d2ca mac80211: mesh pe... |
392 |
|
c2c98fdeb mac80211: optimis... |
393 |
if (!test_sta_flag(sta, WLAN_STA_AUTH)) |
53e805111 mac80211: ignore ... |
394 |
return -EPERM; |
07346f81e mac80211: proper ... |
395 |
spin_lock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
396 397 |
get_random_bytes(&llid, 2); sta->llid = llid; |
57cf8043a nl80211: Move pee... |
398 |
if (sta->plink_state != NL80211_PLINK_LISTEN) { |
07346f81e mac80211: proper ... |
399 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
400 401 |
return -EBUSY; } |
57cf8043a nl80211: Move pee... |
402 |
sta->plink_state = NL80211_PLINK_OPN_SNT; |
c3896d2ca mac80211: mesh pe... |
403 |
mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
07346f81e mac80211: proper ... |
404 |
spin_unlock_bh(&sta->lock); |
0c68ae260 mac80211: convert... |
405 406 407 |
mpl_dbg("Mesh plink: starting establishment with %pM ", sta->sta.addr); |
c3896d2ca mac80211: mesh pe... |
408 |
|
54ef656b0 mac80211: update ... |
409 |
return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, |
17741cdc2 mac80211: share S... |
410 |
sta->sta.addr, llid, 0, 0); |
c3896d2ca mac80211: mesh pe... |
411 412 413 414 |
} void mesh_plink_block(struct sta_info *sta) { |
c93701976 mac80211: avoid s... |
415 416 |
struct ieee80211_sub_if_data *sdata = sta->sdata; bool deactivated; |
07346f81e mac80211: proper ... |
417 |
spin_lock_bh(&sta->lock); |
c93701976 mac80211: avoid s... |
418 |
deactivated = __mesh_plink_deactivate(sta); |
57cf8043a nl80211: Move pee... |
419 |
sta->plink_state = NL80211_PLINK_BLOCKED; |
07346f81e mac80211: proper ... |
420 |
spin_unlock_bh(&sta->lock); |
c93701976 mac80211: avoid s... |
421 422 423 |
if (deactivated) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
c3896d2ca mac80211: mesh pe... |
424 |
} |
c3896d2ca mac80211: mesh pe... |
425 |
|
f698d856f replace net_devic... |
426 |
void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, |
c3896d2ca mac80211: mesh pe... |
427 428 |
size_t len, struct ieee80211_rx_status *rx_status) { |
d0709a651 mac80211: RCU-ify... |
429 |
struct ieee80211_local *local = sdata->local; |
c3896d2ca mac80211: mesh pe... |
430 431 432 |
struct ieee802_11_elems elems; struct sta_info *sta; enum plink_event event; |
54ef656b0 mac80211: update ... |
433 |
enum ieee80211_self_protected_actioncode ftype; |
c3896d2ca mac80211: mesh pe... |
434 |
size_t baselen; |
d12c74528 mac80211: fix pos... |
435 |
bool deactivated, matches_local = true; |
c3896d2ca mac80211: mesh pe... |
436 437 438 |
u8 ie_len; u8 *baseaddr; __le16 plid, llid, reason; |
1460dd158 mac80211: improve... |
439 440 |
#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG static const char *mplstates[] = { |
57cf8043a nl80211: Move pee... |
441 442 443 444 445 446 447 |
[NL80211_PLINK_LISTEN] = "LISTEN", [NL80211_PLINK_OPN_SNT] = "OPN-SNT", [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD", [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD", [NL80211_PLINK_ESTAB] = "ESTAB", [NL80211_PLINK_HOLDING] = "HOLDING", [NL80211_PLINK_BLOCKED] = "BLOCKED" |
1460dd158 mac80211: improve... |
448 449 |
}; #endif |
c3896d2ca mac80211: mesh pe... |
450 |
|
9c80d3dc2 mac80211: fix act... |
451 452 453 |
/* need action_code, aux */ if (len < IEEE80211_MIN_ACTION_SIZE + 3) return; |
c3896d2ca mac80211: mesh pe... |
454 455 456 457 |
if (is_multicast_ether_addr(mgmt->da)) { mpl_dbg("Mesh plink: ignore frame from multicast address"); return; } |
8db098507 mac80211: update ... |
458 459 460 |
baseaddr = mgmt->u.action.u.self_prot.variable; baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt; if (mgmt->u.action.u.self_prot.action_code == |
54ef656b0 mac80211: update ... |
461 |
WLAN_SP_MESH_PEERING_CONFIRM) { |
c3896d2ca mac80211: mesh pe... |
462 |
baseaddr += 4; |
70bdb6b27 mac80211: Fix inv... |
463 |
baselen += 4; |
c3896d2ca mac80211: mesh pe... |
464 465 |
} ieee802_11_parse_elems(baseaddr, len - baselen, &elems); |
8db098507 mac80211: update ... |
466 |
if (!elems.peering) { |
c3896d2ca mac80211: mesh pe... |
467 468 469 470 |
mpl_dbg("Mesh plink: missing necessary peer link ie "); return; } |
b130e5cec nl80211: Introduc... |
471 472 |
if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { |
5cff5e01e mac80211: ignore ... |
473 474 475 476 |
mpl_dbg("Mesh plink: can't establish link with secure peer "); return; } |
c3896d2ca mac80211: mesh pe... |
477 |
|
8db098507 mac80211: update ... |
478 479 480 481 482 483 |
ftype = mgmt->u.action.u.self_prot.action_code; ie_len = elems.peering_len; if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) || (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 && ie_len != 8)) { |
0938393f0 mac80211: update ... |
484 485 486 |
mpl_dbg("Mesh plink: incorrect plink ie length %d %d ", ftype, ie_len); |
c3896d2ca mac80211: mesh pe... |
487 488 |
return; } |
54ef656b0 mac80211: update ... |
489 490 |
if (ftype != WLAN_SP_MESH_PEERING_CLOSE && (!elems.mesh_id || !elems.mesh_config)) { |
c3896d2ca mac80211: mesh pe... |
491 492 493 494 495 496 497 |
mpl_dbg("Mesh plink: missing necessary ie "); return; } /* Note the lines below are correct, the llid in the frame is the plid * from the point of view of this host. */ |
8db098507 mac80211: update ... |
498 |
memcpy(&plid, PLINK_GET_LLID(elems.peering), 2); |
54ef656b0 mac80211: update ... |
499 |
if (ftype == WLAN_SP_MESH_PEERING_CONFIRM || |
8db098507 mac80211: update ... |
500 501 |
(ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) memcpy(&llid, PLINK_GET_PLID(elems.peering), 2); |
c3896d2ca mac80211: mesh pe... |
502 |
|
d0709a651 mac80211: RCU-ify... |
503 |
rcu_read_lock(); |
abe60632f mac80211: make st... |
504 |
sta = sta_info_get(sdata, mgmt->sa); |
54ef656b0 mac80211: update ... |
505 |
if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) { |
c3896d2ca mac80211: mesh pe... |
506 507 |
mpl_dbg("Mesh plink: cls or cnf from unknown peer "); |
d0709a651 mac80211: RCU-ify... |
508 |
rcu_read_unlock(); |
c3896d2ca mac80211: mesh pe... |
509 510 |
return; } |
c2c98fdeb mac80211: optimis... |
511 |
if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { |
53e805111 mac80211: ignore ... |
512 513 514 515 516 |
mpl_dbg("Mesh plink: Action frame from non-authed peer "); rcu_read_unlock(); return; } |
57cf8043a nl80211: Move pee... |
517 |
if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) { |
d0709a651 mac80211: RCU-ify... |
518 |
rcu_read_unlock(); |
c3896d2ca mac80211: mesh pe... |
519 520 521 522 523 |
return; } /* Now we will figure out the appropriate event... */ event = PLINK_UNDEFINED; |
54ef656b0 mac80211: update ... |
524 525 |
if (ftype != WLAN_SP_MESH_PEERING_CLOSE && (!mesh_matches_local(&elems, sdata))) { |
d12c74528 mac80211: fix pos... |
526 |
matches_local = false; |
c3896d2ca mac80211: mesh pe... |
527 |
switch (ftype) { |
54ef656b0 mac80211: update ... |
528 |
case WLAN_SP_MESH_PEERING_OPEN: |
c3896d2ca mac80211: mesh pe... |
529 530 |
event = OPN_RJCT; break; |
54ef656b0 mac80211: update ... |
531 |
case WLAN_SP_MESH_PEERING_CONFIRM: |
c3896d2ca mac80211: mesh pe... |
532 533 |
event = CNF_RJCT; break; |
54ef656b0 mac80211: update ... |
534 |
default: |
c3896d2ca mac80211: mesh pe... |
535 536 |
break; } |
d12c74528 mac80211: fix pos... |
537 538 539 540 |
} if (!sta && !matches_local) { rcu_read_unlock(); |
54ef656b0 mac80211: update ... |
541 |
reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); |
d12c74528 mac80211: fix pos... |
542 |
llid = 0; |
54ef656b0 mac80211: update ... |
543 544 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, mgmt->sa, llid, plid, reason); |
d12c74528 mac80211: fix pos... |
545 |
return; |
c3896d2ca mac80211: mesh pe... |
546 |
} else if (!sta) { |
54ef656b0 mac80211: update ... |
547 |
/* ftype == WLAN_SP_MESH_PEERING_OPEN */ |
881d948c2 wireless: restric... |
548 |
u32 rates; |
34e895075 mac80211: allow s... |
549 550 |
rcu_read_unlock(); |
c3896d2ca mac80211: mesh pe... |
551 552 553 554 555 556 557 |
if (!mesh_plink_free_count(sdata)) { mpl_dbg("Mesh plink error: no more free plinks "); return; } rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); |
739522baa mac80211: set HT ... |
558 |
sta = mesh_plink_alloc(sdata, mgmt->sa, rates, &elems); |
73651ee63 mac80211: split s... |
559 |
if (!sta) { |
c3896d2ca mac80211: mesh pe... |
560 561 562 563 |
mpl_dbg("Mesh plink error: plink table full "); return; } |
34e895075 mac80211: allow s... |
564 |
if (sta_info_insert_rcu(sta)) { |
73651ee63 mac80211: split s... |
565 566 567 |
rcu_read_unlock(); return; } |
c3896d2ca mac80211: mesh pe... |
568 |
event = OPN_ACPT; |
07346f81e mac80211: proper ... |
569 |
spin_lock_bh(&sta->lock); |
d12c74528 mac80211: fix pos... |
570 |
} else if (matches_local) { |
07346f81e mac80211: proper ... |
571 |
spin_lock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
572 |
switch (ftype) { |
54ef656b0 mac80211: update ... |
573 |
case WLAN_SP_MESH_PEERING_OPEN: |
c3896d2ca mac80211: mesh pe... |
574 |
if (!mesh_plink_free_count(sdata) || |
d0709a651 mac80211: RCU-ify... |
575 |
(sta->plid && sta->plid != plid)) |
c3896d2ca mac80211: mesh pe... |
576 577 578 579 |
event = OPN_IGNR; else event = OPN_ACPT; break; |
54ef656b0 mac80211: update ... |
580 |
case WLAN_SP_MESH_PEERING_CONFIRM: |
c3896d2ca mac80211: mesh pe... |
581 |
if (!mesh_plink_free_count(sdata) || |
d0709a651 mac80211: RCU-ify... |
582 |
(sta->llid != llid || sta->plid != plid)) |
c3896d2ca mac80211: mesh pe... |
583 584 585 586 |
event = CNF_IGNR; else event = CNF_ACPT; break; |
54ef656b0 mac80211: update ... |
587 |
case WLAN_SP_MESH_PEERING_CLOSE: |
57cf8043a nl80211: Move pee... |
588 |
if (sta->plink_state == NL80211_PLINK_ESTAB) |
c3896d2ca mac80211: mesh pe... |
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 |
/* Do not check for llid or plid. This does not * follow the standard but since multiple plinks * per sta are not supported, it is necessary in * order to avoid a livelock when MP A sees an * establish peer link to MP B but MP B does not * see it. This can be caused by a timeout in * B's peer link establishment or B beign * restarted. */ event = CLS_ACPT; else if (sta->plid != plid) event = CLS_IGNR; else if (ie_len == 7 && sta->llid != llid) event = CLS_IGNR; else event = CLS_ACPT; break; default: mpl_dbg("Mesh plink: unknown frame subtype "); |
07346f81e mac80211: proper ... |
609 |
spin_unlock_bh(&sta->lock); |
d0709a651 mac80211: RCU-ify... |
610 |
rcu_read_unlock(); |
c3896d2ca mac80211: mesh pe... |
611 612 |
return; } |
d12c74528 mac80211: fix pos... |
613 614 |
} else { spin_lock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
615 |
} |
1460dd158 mac80211: improve... |
616 617 618 |
mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d ", mgmt->sa, mplstates[sta->plink_state], |
0c68ae260 mac80211: convert... |
619 620 |
le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), event); |
c3896d2ca mac80211: mesh pe... |
621 622 623 |
reason = 0; switch (sta->plink_state) { /* spin_unlock as soon as state is updated at each case */ |
57cf8043a nl80211: Move pee... |
624 |
case NL80211_PLINK_LISTEN: |
c3896d2ca mac80211: mesh pe... |
625 626 627 |
switch (event) { case CLS_ACPT: mesh_plink_fsm_restart(sta); |
07346f81e mac80211: proper ... |
628 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
629 630 |
break; case OPN_ACPT: |
57cf8043a nl80211: Move pee... |
631 |
sta->plink_state = NL80211_PLINK_OPN_RCVD; |
c3896d2ca mac80211: mesh pe... |
632 633 634 635 |
sta->plid = plid; get_random_bytes(&llid, 2); sta->llid = llid; mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
07346f81e mac80211: proper ... |
636 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
637 638 639 640 641 642 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, sta->sta.addr, llid, 0, 0); mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, sta->sta.addr, llid, plid, 0); |
c3896d2ca mac80211: mesh pe... |
643 644 |
break; default: |
07346f81e mac80211: proper ... |
645 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
646 647 648 |
break; } break; |
57cf8043a nl80211: Move pee... |
649 |
case NL80211_PLINK_OPN_SNT: |
c3896d2ca mac80211: mesh pe... |
650 651 652 |
switch (event) { case OPN_RJCT: case CNF_RJCT: |
54ef656b0 mac80211: update ... |
653 |
reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); |
c3896d2ca mac80211: mesh pe... |
654 655 |
case CLS_ACPT: if (!reason) |
54ef656b0 mac80211: update ... |
656 |
reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); |
c3896d2ca mac80211: mesh pe... |
657 |
sta->reason = reason; |
57cf8043a nl80211: Move pee... |
658 |
sta->plink_state = NL80211_PLINK_HOLDING; |
c3896d2ca mac80211: mesh pe... |
659 660 661 662 663 |
if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) sta->ignore_plink_timer = true; llid = sta->llid; |
07346f81e mac80211: proper ... |
664 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
665 666 667 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, sta->sta.addr, llid, plid, reason); |
c3896d2ca mac80211: mesh pe... |
668 669 670 |
break; case OPN_ACPT: /* retry timer is left untouched */ |
57cf8043a nl80211: Move pee... |
671 |
sta->plink_state = NL80211_PLINK_OPN_RCVD; |
c3896d2ca mac80211: mesh pe... |
672 673 |
sta->plid = plid; llid = sta->llid; |
07346f81e mac80211: proper ... |
674 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
675 676 677 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, sta->sta.addr, llid, plid, 0); |
c3896d2ca mac80211: mesh pe... |
678 679 |
break; case CNF_ACPT: |
57cf8043a nl80211: Move pee... |
680 |
sta->plink_state = NL80211_PLINK_CNF_RCVD; |
c3896d2ca mac80211: mesh pe... |
681 682 683 |
if (!mod_plink_timer(sta, dot11MeshConfirmTimeout(sdata))) sta->ignore_plink_timer = true; |
07346f81e mac80211: proper ... |
684 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
685 686 |
break; default: |
07346f81e mac80211: proper ... |
687 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
688 689 690 |
break; } break; |
57cf8043a nl80211: Move pee... |
691 |
case NL80211_PLINK_OPN_RCVD: |
c3896d2ca mac80211: mesh pe... |
692 693 694 |
switch (event) { case OPN_RJCT: case CNF_RJCT: |
54ef656b0 mac80211: update ... |
695 |
reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); |
c3896d2ca mac80211: mesh pe... |
696 697 |
case CLS_ACPT: if (!reason) |
54ef656b0 mac80211: update ... |
698 |
reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); |
c3896d2ca mac80211: mesh pe... |
699 |
sta->reason = reason; |
57cf8043a nl80211: Move pee... |
700 |
sta->plink_state = NL80211_PLINK_HOLDING; |
c3896d2ca mac80211: mesh pe... |
701 702 703 704 705 |
if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) sta->ignore_plink_timer = true; llid = sta->llid; |
07346f81e mac80211: proper ... |
706 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
707 708 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, sta->sta.addr, llid, plid, reason); |
c3896d2ca mac80211: mesh pe... |
709 710 711 |
break; case OPN_ACPT: llid = sta->llid; |
07346f81e mac80211: proper ... |
712 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
713 714 715 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, sta->sta.addr, llid, plid, 0); |
c3896d2ca mac80211: mesh pe... |
716 717 |
break; case CNF_ACPT: |
d0709a651 mac80211: RCU-ify... |
718 |
del_timer(&sta->plink_timer); |
57cf8043a nl80211: Move pee... |
719 |
sta->plink_state = NL80211_PLINK_ESTAB; |
07346f81e mac80211: proper ... |
720 |
spin_unlock_bh(&sta->lock); |
c93701976 mac80211: avoid s... |
721 722 |
mesh_plink_inc_estab_count(sdata); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
0c68ae260 mac80211: convert... |
723 724 725 |
mpl_dbg("Mesh plink with %pM ESTABLISHED ", sta->sta.addr); |
c3896d2ca mac80211: mesh pe... |
726 727 |
break; default: |
07346f81e mac80211: proper ... |
728 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
729 730 731 |
break; } break; |
57cf8043a nl80211: Move pee... |
732 |
case NL80211_PLINK_CNF_RCVD: |
c3896d2ca mac80211: mesh pe... |
733 734 735 |
switch (event) { case OPN_RJCT: case CNF_RJCT: |
54ef656b0 mac80211: update ... |
736 |
reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); |
c3896d2ca mac80211: mesh pe... |
737 738 |
case CLS_ACPT: if (!reason) |
54ef656b0 mac80211: update ... |
739 |
reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); |
c3896d2ca mac80211: mesh pe... |
740 |
sta->reason = reason; |
57cf8043a nl80211: Move pee... |
741 |
sta->plink_state = NL80211_PLINK_HOLDING; |
c3896d2ca mac80211: mesh pe... |
742 743 744 745 746 |
if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) sta->ignore_plink_timer = true; llid = sta->llid; |
07346f81e mac80211: proper ... |
747 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
748 749 750 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, sta->sta.addr, llid, plid, reason); |
ff59dc76e mac80211: add mis... |
751 |
break; |
c3896d2ca mac80211: mesh pe... |
752 |
case OPN_ACPT: |
d0709a651 mac80211: RCU-ify... |
753 |
del_timer(&sta->plink_timer); |
57cf8043a nl80211: Move pee... |
754 |
sta->plink_state = NL80211_PLINK_ESTAB; |
07346f81e mac80211: proper ... |
755 |
spin_unlock_bh(&sta->lock); |
c93701976 mac80211: avoid s... |
756 757 |
mesh_plink_inc_estab_count(sdata); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
0c68ae260 mac80211: convert... |
758 759 760 |
mpl_dbg("Mesh plink with %pM ESTABLISHED ", sta->sta.addr); |
54ef656b0 mac80211: update ... |
761 762 763 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, sta->sta.addr, llid, plid, 0); |
c3896d2ca mac80211: mesh pe... |
764 765 |
break; default: |
07346f81e mac80211: proper ... |
766 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
767 768 769 |
break; } break; |
57cf8043a nl80211: Move pee... |
770 |
case NL80211_PLINK_ESTAB: |
c3896d2ca mac80211: mesh pe... |
771 772 |
switch (event) { case CLS_ACPT: |
54ef656b0 mac80211: update ... |
773 |
reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); |
c3896d2ca mac80211: mesh pe... |
774 |
sta->reason = reason; |
c93701976 mac80211: avoid s... |
775 |
deactivated = __mesh_plink_deactivate(sta); |
57cf8043a nl80211: Move pee... |
776 |
sta->plink_state = NL80211_PLINK_HOLDING; |
c3896d2ca mac80211: mesh pe... |
777 |
llid = sta->llid; |
d0709a651 mac80211: RCU-ify... |
778 |
mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
07346f81e mac80211: proper ... |
779 |
spin_unlock_bh(&sta->lock); |
c93701976 mac80211: avoid s... |
780 781 |
if (deactivated) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
54ef656b0 mac80211: update ... |
782 783 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, sta->sta.addr, llid, plid, reason); |
c3896d2ca mac80211: mesh pe... |
784 785 786 |
break; case OPN_ACPT: llid = sta->llid; |
07346f81e mac80211: proper ... |
787 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
788 789 790 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, sta->sta.addr, llid, plid, 0); |
c3896d2ca mac80211: mesh pe... |
791 792 |
break; default: |
07346f81e mac80211: proper ... |
793 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
794 795 796 |
break; } break; |
57cf8043a nl80211: Move pee... |
797 |
case NL80211_PLINK_HOLDING: |
c3896d2ca mac80211: mesh pe... |
798 799 |
switch (event) { case CLS_ACPT: |
d0709a651 mac80211: RCU-ify... |
800 |
if (del_timer(&sta->plink_timer)) |
c3896d2ca mac80211: mesh pe... |
801 |
sta->ignore_plink_timer = 1; |
c3896d2ca mac80211: mesh pe... |
802 |
mesh_plink_fsm_restart(sta); |
07346f81e mac80211: proper ... |
803 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
804 805 806 807 808 809 810 |
break; case OPN_ACPT: case CNF_ACPT: case OPN_RJCT: case CNF_RJCT: llid = sta->llid; reason = sta->reason; |
07346f81e mac80211: proper ... |
811 |
spin_unlock_bh(&sta->lock); |
54ef656b0 mac80211: update ... |
812 813 |
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, sta->sta.addr, llid, plid, reason); |
c3896d2ca mac80211: mesh pe... |
814 815 |
break; default: |
07346f81e mac80211: proper ... |
816 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
817 818 819 |
} break; default: |
b4e08ea14 mac80211: add PLI... |
820 |
/* should not get here, PLINK_BLOCKED is dealt with at the |
3ad2f3fbb tree-wide: Assort... |
821 |
* beginning of the function |
c3896d2ca mac80211: mesh pe... |
822 |
*/ |
07346f81e mac80211: proper ... |
823 |
spin_unlock_bh(&sta->lock); |
c3896d2ca mac80211: mesh pe... |
824 825 |
break; } |
d0709a651 mac80211: RCU-ify... |
826 827 |
rcu_read_unlock(); |
c3896d2ca mac80211: mesh pe... |
828 |
} |