diff options
-rw-r--r-- | net/mac80211/mesh_plink.c | 40 | ||||
-rw-r--r-- | net/mac80211/mesh_ps.c | 3 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 4 |
3 files changed, 38 insertions, 9 deletions
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index ee2a97f31732..fadc3e189131 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -615,9 +615,40 @@ static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) | |||
615 | add_timer(&sta->plink_timer); | 615 | add_timer(&sta->plink_timer); |
616 | } | 616 | } |
617 | 617 | ||
618 | static bool llid_in_use(struct ieee80211_sub_if_data *sdata, | ||
619 | __le16 llid) | ||
620 | { | ||
621 | struct ieee80211_local *local = sdata->local; | ||
622 | bool in_use = false; | ||
623 | struct sta_info *sta; | ||
624 | |||
625 | rcu_read_lock(); | ||
626 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | ||
627 | if (!memcmp(&sta->llid, &llid, sizeof(llid))) { | ||
628 | in_use = true; | ||
629 | break; | ||
630 | } | ||
631 | } | ||
632 | rcu_read_unlock(); | ||
633 | |||
634 | return in_use; | ||
635 | } | ||
636 | |||
637 | static __le16 mesh_get_new_llid(struct ieee80211_sub_if_data *sdata) | ||
638 | { | ||
639 | u16 llid; | ||
640 | |||
641 | do { | ||
642 | get_random_bytes(&llid, sizeof(llid)); | ||
643 | /* for mesh PS we still only have the AID range for TIM bits */ | ||
644 | llid = (llid % IEEE80211_MAX_AID) + 1; | ||
645 | } while (llid_in_use(sdata, cpu_to_le16(llid))); | ||
646 | |||
647 | return cpu_to_le16(llid); | ||
648 | } | ||
649 | |||
618 | u32 mesh_plink_open(struct sta_info *sta) | 650 | u32 mesh_plink_open(struct sta_info *sta) |
619 | { | 651 | { |
620 | __le16 llid; | ||
621 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 652 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
622 | u32 changed; | 653 | u32 changed; |
623 | 654 | ||
@@ -625,8 +656,7 @@ u32 mesh_plink_open(struct sta_info *sta) | |||
625 | return 0; | 656 | return 0; |
626 | 657 | ||
627 | spin_lock_bh(&sta->lock); | 658 | spin_lock_bh(&sta->lock); |
628 | get_random_bytes(&llid, 2); | 659 | sta->llid = mesh_get_new_llid(sdata); |
629 | sta->llid = llid; | ||
630 | if (sta->plink_state != NL80211_PLINK_LISTEN && | 660 | if (sta->plink_state != NL80211_PLINK_LISTEN && |
631 | sta->plink_state != NL80211_PLINK_BLOCKED) { | 661 | sta->plink_state != NL80211_PLINK_BLOCKED) { |
632 | spin_unlock_bh(&sta->lock); | 662 | spin_unlock_bh(&sta->lock); |
@@ -643,7 +673,7 @@ u32 mesh_plink_open(struct sta_info *sta) | |||
643 | changed = ieee80211_mps_local_status_update(sdata); | 673 | changed = ieee80211_mps_local_status_update(sdata); |
644 | 674 | ||
645 | mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, | 675 | mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, |
646 | sta->sta.addr, llid, 0, 0); | 676 | sta->sta.addr, sta->llid, 0, 0); |
647 | return changed; | 677 | return changed; |
648 | } | 678 | } |
649 | 679 | ||
@@ -719,7 +749,7 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata, | |||
719 | break; | 749 | break; |
720 | case OPN_ACPT: | 750 | case OPN_ACPT: |
721 | sta->plink_state = NL80211_PLINK_OPN_RCVD; | 751 | sta->plink_state = NL80211_PLINK_OPN_RCVD; |
722 | get_random_bytes(&sta->llid, 2); | 752 | sta->llid = mesh_get_new_llid(sdata); |
723 | mesh_plink_timer_set(sta, | 753 | mesh_plink_timer_set(sta, |
724 | mshcfg->dot11MeshRetryTimeout); | 754 | mshcfg->dot11MeshRetryTimeout); |
725 | 755 | ||
diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c index 0f79b78b5e86..9493868ef6c3 100644 --- a/net/mac80211/mesh_ps.c +++ b/net/mac80211/mesh_ps.c | |||
@@ -576,10 +576,9 @@ void ieee80211_mps_frame_release(struct sta_info *sta, | |||
576 | int ac, buffer_local = 0; | 576 | int ac, buffer_local = 0; |
577 | bool has_buffered = false; | 577 | bool has_buffered = false; |
578 | 578 | ||
579 | /* TIM map only for LLID <= IEEE80211_MAX_AID */ | ||
580 | if (sta->plink_state == NL80211_PLINK_ESTAB) | 579 | if (sta->plink_state == NL80211_PLINK_ESTAB) |
581 | has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len, | 580 | has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len, |
582 | le16_to_cpu(sta->llid) % IEEE80211_MAX_AID); | 581 | le16_to_cpu(sta->llid)); |
583 | 582 | ||
584 | if (has_buffered) | 583 | if (has_buffered) |
585 | mps_dbg(sta->sdata, "%pM indicates buffered frames\n", | 584 | mps_dbg(sta->sdata, "%pM indicates buffered frames\n", |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 1eb66e26e49d..7a9151590cce 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -630,8 +630,8 @@ void sta_info_recalc_tim(struct sta_info *sta) | |||
630 | #ifdef CONFIG_MAC80211_MESH | 630 | #ifdef CONFIG_MAC80211_MESH |
631 | } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) { | 631 | } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) { |
632 | ps = &sta->sdata->u.mesh.ps; | 632 | ps = &sta->sdata->u.mesh.ps; |
633 | /* TIM map only for PLID <= IEEE80211_MAX_AID */ | 633 | /* TIM map only for 1 <= PLID <= IEEE80211_MAX_AID */ |
634 | id = le16_to_cpu(sta->plid) % IEEE80211_MAX_AID; | 634 | id = le16_to_cpu(sta->plid) % (IEEE80211_MAX_AID + 1); |
635 | #endif | 635 | #endif |
636 | } else { | 636 | } else { |
637 | return; | 637 | return; |