Index: chromeos/compat-wireless/net/mac80211/mesh_plink.c |
diff --git a/chromeos/compat-wireless/net/mac80211/mesh_plink.c b/chromeos/compat-wireless/net/mac80211/mesh_plink.c |
index ea13a80a476c1fe0db6dc5e0059e2014f340926e..1c91f0f3c3079ba9f6a8d94097d6e637b948cdad 100644 |
--- a/chromeos/compat-wireless/net/mac80211/mesh_plink.c |
+++ b/chromeos/compat-wireless/net/mac80211/mesh_plink.c |
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m |
enum plink_event event; |
enum plink_frame_type ftype; |
size_t baselen; |
- bool deactivated; |
+ bool deactivated, matches_local = true; |
u8 ie_len; |
u8 *baseaddr; |
__le16 plid, llid, reason; |
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m |
/* Now we will figure out the appropriate event... */ |
event = PLINK_UNDEFINED; |
if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { |
+ matches_local = false; |
switch (ftype) { |
case PLINK_OPEN: |
event = OPN_RJCT; |
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m |
/* avoid warning */ |
break; |
} |
- spin_lock_bh(&sta->lock); |
+ } |
+ |
+ if (!sta && !matches_local) { |
+ rcu_read_unlock(); |
+ reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); |
+ llid = 0; |
+ mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid, |
+ plid, reason); |
+ return; |
} else if (!sta) { |
/* ftype == PLINK_OPEN */ |
u32 rates; |
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m |
} |
event = OPN_ACPT; |
spin_lock_bh(&sta->lock); |
- } else { |
+ } else if (matches_local) { |
spin_lock_bh(&sta->lock); |
switch (ftype) { |
case PLINK_OPEN: |
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m |
rcu_read_unlock(); |
return; |
} |
+ } else { |
+ spin_lock_bh(&sta->lock); |
} |
mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", |