diff options
Diffstat (limited to 'net/mac80211/mesh_plink.c')
-rw-r--r-- | net/mac80211/mesh_plink.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 41ef1b476442..4e53c4cbca9e 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -31,6 +31,12 @@ #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) +/* We only need a valid sta if user configured a minimum rssi_threshold. */ +#define rssi_threshold_check(sta, sdata) \ + (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\ + (sta && (s8) -ewma_read(&sta->avg_signal) > \ + sdata->u.mesh.mshcfg.rssi_threshold)) + enum plink_event { PLINK_UNDEFINED, OPN_ACPT, @@ -96,9 +102,9 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, if (!sta) return NULL; - sta_info_move_state(sta, IEEE80211_STA_AUTH); - sta_info_move_state(sta, IEEE80211_STA_ASSOC); - sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); + sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); + sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); + sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); set_sta_flag(sta, WLAN_STA_WME); @@ -172,7 +178,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 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 + + skb = dev_alloc_skb(local->tx_headroom + hdr_len + 2 + /* capability info */ 2 + /* AID */ @@ -186,7 +192,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, sdata->u.mesh.ie_len); if (!skb) return -1; - skb_reserve(skb, local->hw.extra_tx_headroom); + skb_reserve(skb, local->tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); memset(mgmt, 0, hdr_len); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | @@ -301,7 +307,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, if (mesh_peer_accepts_plinks(elems) && sta->plink_state == NL80211_PLINK_LISTEN && sdata->u.mesh.accepting_plinks && - sdata->u.mesh.mshcfg.auto_open_plinks) + sdata->u.mesh.mshcfg.auto_open_plinks && + rssi_threshold_check(sta, sdata)) mesh_plink_open(sta); rcu_read_unlock(); @@ -531,6 +538,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m return; } + if (ftype == WLAN_SP_MESH_PEERING_OPEN && + !rssi_threshold_check(sta, sdata)) { + mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n", + mgmt->sa); + rcu_read_unlock(); + return; + } + if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); rcu_read_unlock(); |