aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh_plink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mesh_plink.c')
-rw-r--r--net/mac80211/mesh_plink.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 44b53931ba5e..84e5b056af02 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
105 if (!sta) 105 if (!sta)
106 return NULL; 106 return NULL;
107 107
108 sta->flags = WLAN_STA_AUTHORIZED; 108 sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH;
109 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 109 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
110 rate_control_rate_init(sta); 110 rate_control_rate_init(sta);
111 111
@@ -161,7 +161,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
161 __le16 reason) { 161 __le16 reason) {
162 struct ieee80211_local *local = sdata->local; 162 struct ieee80211_local *local = sdata->local;
163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + 163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
164 sdata->u.mesh.vendor_ie_len); 164 sdata->u.mesh.ie_len);
165 struct ieee80211_mgmt *mgmt; 165 struct ieee80211_mgmt *mgmt;
166 bool include_plid = false; 166 bool include_plid = false;
167 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; 167 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
@@ -237,8 +237,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
237 return 0; 237 return 0;
238} 238}
239 239
240void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata, 240void mesh_neighbour_update(u8 *hw_addr, u32 rates,
241 bool peer_accepting_plinks) 241 struct ieee80211_sub_if_data *sdata,
242 struct ieee802_11_elems *elems)
242{ 243{
243 struct ieee80211_local *local = sdata->local; 244 struct ieee80211_local *local = sdata->local;
244 struct sta_info *sta; 245 struct sta_info *sta;
@@ -248,8 +249,14 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data
248 sta = sta_info_get(sdata, hw_addr); 249 sta = sta_info_get(sdata, hw_addr);
249 if (!sta) { 250 if (!sta) {
250 rcu_read_unlock(); 251 rcu_read_unlock();
251 252 /* Userspace handles peer allocation when security is enabled
252 sta = mesh_plink_alloc(sdata, hw_addr, rates); 253 * */
254 if (sdata->u.mesh.is_secure)
255 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr,
256 elems->ie_start, elems->total_len,
257 GFP_KERNEL);
258 else
259 sta = mesh_plink_alloc(sdata, hw_addr, rates);
253 if (!sta) 260 if (!sta)
254 return; 261 return;
255 if (sta_info_insert_rcu(sta)) { 262 if (sta_info_insert_rcu(sta)) {
@@ -260,7 +267,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data
260 267
261 sta->last_rx = jiffies; 268 sta->last_rx = jiffies;
262 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 269 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
263 if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN && 270 if (mesh_peer_accepts_plinks(elems) &&
271 sta->plink_state == PLINK_LISTEN &&
264 sdata->u.mesh.accepting_plinks && 272 sdata->u.mesh.accepting_plinks &&
265 sdata->u.mesh.mshcfg.auto_open_plinks) 273 sdata->u.mesh.mshcfg.auto_open_plinks)
266 mesh_plink_open(sta); 274 mesh_plink_open(sta);
@@ -372,6 +380,9 @@ int mesh_plink_open(struct sta_info *sta)
372 __le16 llid; 380 __le16 llid;
373 struct ieee80211_sub_if_data *sdata = sta->sdata; 381 struct ieee80211_sub_if_data *sdata = sta->sdata;
374 382
383 if (!test_sta_flags(sta, WLAN_STA_AUTH))
384 return -EPERM;
385
375 spin_lock_bh(&sta->lock); 386 spin_lock_bh(&sta->lock);
376 get_random_bytes(&llid, 2); 387 get_random_bytes(&llid, 2);
377 sta->llid = llid; 388 sta->llid = llid;
@@ -449,6 +460,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
449 mpl_dbg("Mesh plink: missing necessary peer link ie\n"); 460 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
450 return; 461 return;
451 } 462 }
463 if (elems.rsn_len && !sdata->u.mesh.is_secure) {
464 mpl_dbg("Mesh plink: can't establish link with secure peer\n");
465 return;
466 }
452 467
453 ftype = mgmt->u.action.u.plink_action.action_code; 468 ftype = mgmt->u.action.u.plink_action.action_code;
454 ie_len = elems.peer_link_len; 469 ie_len = elems.peer_link_len;
@@ -480,6 +495,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
480 return; 495 return;
481 } 496 }
482 497
498 if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) {
499 mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
500 rcu_read_unlock();
501 return;
502 }
503
483 if (sta && sta->plink_state == PLINK_BLOCKED) { 504 if (sta && sta->plink_state == PLINK_BLOCKED) {
484 rcu_read_unlock(); 505 rcu_read_unlock();
485 return; 506 return;