mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
cfg80211: refactor cfg80211_bss_update
This patch implements minor refactoring for cfg80211_bss_update function. Code path for updating known BSS is extracted into dedicated cfg80211_update_known_bss function. Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com> Link: https://lore.kernel.org/r/20190726163922.27509-2-sergey.matyukevich.os@quantenna.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
committed by
Johannes Berg
parent
ae6fa4d5e9
commit
3ab8227d3e
@@ -1091,6 +1091,93 @@ struct cfg80211_non_tx_bss {
|
|||||||
u8 bssid_index;
|
u8 bssid_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
|
||||||
|
struct cfg80211_internal_bss *known,
|
||||||
|
struct cfg80211_internal_bss *new,
|
||||||
|
bool signal_valid)
|
||||||
|
{
|
||||||
|
lockdep_assert_held(&rdev->bss_lock);
|
||||||
|
|
||||||
|
/* Update IEs */
|
||||||
|
if (rcu_access_pointer(new->pub.proberesp_ies)) {
|
||||||
|
const struct cfg80211_bss_ies *old;
|
||||||
|
|
||||||
|
old = rcu_access_pointer(known->pub.proberesp_ies);
|
||||||
|
|
||||||
|
rcu_assign_pointer(known->pub.proberesp_ies,
|
||||||
|
new->pub.proberesp_ies);
|
||||||
|
/* Override possible earlier Beacon frame IEs */
|
||||||
|
rcu_assign_pointer(known->pub.ies,
|
||||||
|
new->pub.proberesp_ies);
|
||||||
|
if (old)
|
||||||
|
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
|
||||||
|
} else if (rcu_access_pointer(new->pub.beacon_ies)) {
|
||||||
|
const struct cfg80211_bss_ies *old;
|
||||||
|
struct cfg80211_internal_bss *bss;
|
||||||
|
|
||||||
|
if (known->pub.hidden_beacon_bss &&
|
||||||
|
!list_empty(&known->hidden_list)) {
|
||||||
|
const struct cfg80211_bss_ies *f;
|
||||||
|
|
||||||
|
/* The known BSS struct is one of the probe
|
||||||
|
* response members of a group, but we're
|
||||||
|
* receiving a beacon (beacon_ies in the new
|
||||||
|
* bss is used). This can only mean that the
|
||||||
|
* AP changed its beacon from not having an
|
||||||
|
* SSID to showing it, which is confusing so
|
||||||
|
* drop this information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
f = rcu_access_pointer(new->pub.beacon_ies);
|
||||||
|
kfree_rcu((struct cfg80211_bss_ies *)f, rcu_head);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
old = rcu_access_pointer(known->pub.beacon_ies);
|
||||||
|
|
||||||
|
rcu_assign_pointer(known->pub.beacon_ies, new->pub.beacon_ies);
|
||||||
|
|
||||||
|
/* Override IEs if they were from a beacon before */
|
||||||
|
if (old == rcu_access_pointer(known->pub.ies))
|
||||||
|
rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
|
||||||
|
|
||||||
|
/* Assign beacon IEs to all sub entries */
|
||||||
|
list_for_each_entry(bss, &known->hidden_list, hidden_list) {
|
||||||
|
const struct cfg80211_bss_ies *ies;
|
||||||
|
|
||||||
|
ies = rcu_access_pointer(bss->pub.beacon_ies);
|
||||||
|
WARN_ON(ies != old);
|
||||||
|
|
||||||
|
rcu_assign_pointer(bss->pub.beacon_ies,
|
||||||
|
new->pub.beacon_ies);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old)
|
||||||
|
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
|
||||||
|
}
|
||||||
|
|
||||||
|
known->pub.beacon_interval = new->pub.beacon_interval;
|
||||||
|
|
||||||
|
/* don't update the signal if beacon was heard on
|
||||||
|
* adjacent channel.
|
||||||
|
*/
|
||||||
|
if (signal_valid)
|
||||||
|
known->pub.signal = new->pub.signal;
|
||||||
|
known->pub.capability = new->pub.capability;
|
||||||
|
known->ts = new->ts;
|
||||||
|
known->ts_boottime = new->ts_boottime;
|
||||||
|
known->parent_tsf = new->parent_tsf;
|
||||||
|
known->pub.chains = new->pub.chains;
|
||||||
|
memcpy(known->pub.chain_signal, new->pub.chain_signal,
|
||||||
|
IEEE80211_MAX_CHAINS);
|
||||||
|
ether_addr_copy(known->parent_bssid, new->parent_bssid);
|
||||||
|
known->pub.max_bssid_indicator = new->pub.max_bssid_indicator;
|
||||||
|
known->pub.bssid_index = new->pub.bssid_index;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returned bss is reference counted and must be cleaned up appropriately. */
|
/* Returned bss is reference counted and must be cleaned up appropriately. */
|
||||||
struct cfg80211_internal_bss *
|
struct cfg80211_internal_bss *
|
||||||
cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
||||||
@@ -1114,88 +1201,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
|||||||
found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR);
|
found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR);
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
/* Update IEs */
|
if (!cfg80211_update_known_bss(rdev, found, tmp, signal_valid))
|
||||||
if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
|
goto drop;
|
||||||
const struct cfg80211_bss_ies *old;
|
|
||||||
|
|
||||||
old = rcu_access_pointer(found->pub.proberesp_ies);
|
|
||||||
|
|
||||||
rcu_assign_pointer(found->pub.proberesp_ies,
|
|
||||||
tmp->pub.proberesp_ies);
|
|
||||||
/* Override possible earlier Beacon frame IEs */
|
|
||||||
rcu_assign_pointer(found->pub.ies,
|
|
||||||
tmp->pub.proberesp_ies);
|
|
||||||
if (old)
|
|
||||||
kfree_rcu((struct cfg80211_bss_ies *)old,
|
|
||||||
rcu_head);
|
|
||||||
} else if (rcu_access_pointer(tmp->pub.beacon_ies)) {
|
|
||||||
const struct cfg80211_bss_ies *old;
|
|
||||||
struct cfg80211_internal_bss *bss;
|
|
||||||
|
|
||||||
if (found->pub.hidden_beacon_bss &&
|
|
||||||
!list_empty(&found->hidden_list)) {
|
|
||||||
const struct cfg80211_bss_ies *f;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The found BSS struct is one of the probe
|
|
||||||
* response members of a group, but we're
|
|
||||||
* receiving a beacon (beacon_ies in the tmp
|
|
||||||
* bss is used). This can only mean that the
|
|
||||||
* AP changed its beacon from not having an
|
|
||||||
* SSID to showing it, which is confusing so
|
|
||||||
* drop this information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
f = rcu_access_pointer(tmp->pub.beacon_ies);
|
|
||||||
kfree_rcu((struct cfg80211_bss_ies *)f,
|
|
||||||
rcu_head);
|
|
||||||
goto drop;
|
|
||||||
}
|
|
||||||
|
|
||||||
old = rcu_access_pointer(found->pub.beacon_ies);
|
|
||||||
|
|
||||||
rcu_assign_pointer(found->pub.beacon_ies,
|
|
||||||
tmp->pub.beacon_ies);
|
|
||||||
|
|
||||||
/* Override IEs if they were from a beacon before */
|
|
||||||
if (old == rcu_access_pointer(found->pub.ies))
|
|
||||||
rcu_assign_pointer(found->pub.ies,
|
|
||||||
tmp->pub.beacon_ies);
|
|
||||||
|
|
||||||
/* Assign beacon IEs to all sub entries */
|
|
||||||
list_for_each_entry(bss, &found->hidden_list,
|
|
||||||
hidden_list) {
|
|
||||||
const struct cfg80211_bss_ies *ies;
|
|
||||||
|
|
||||||
ies = rcu_access_pointer(bss->pub.beacon_ies);
|
|
||||||
WARN_ON(ies != old);
|
|
||||||
|
|
||||||
rcu_assign_pointer(bss->pub.beacon_ies,
|
|
||||||
tmp->pub.beacon_ies);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (old)
|
|
||||||
kfree_rcu((struct cfg80211_bss_ies *)old,
|
|
||||||
rcu_head);
|
|
||||||
}
|
|
||||||
|
|
||||||
found->pub.beacon_interval = tmp->pub.beacon_interval;
|
|
||||||
/*
|
|
||||||
* don't update the signal if beacon was heard on
|
|
||||||
* adjacent channel.
|
|
||||||
*/
|
|
||||||
if (signal_valid)
|
|
||||||
found->pub.signal = tmp->pub.signal;
|
|
||||||
found->pub.capability = tmp->pub.capability;
|
|
||||||
found->ts = tmp->ts;
|
|
||||||
found->ts_boottime = tmp->ts_boottime;
|
|
||||||
found->parent_tsf = tmp->parent_tsf;
|
|
||||||
found->pub.chains = tmp->pub.chains;
|
|
||||||
memcpy(found->pub.chain_signal, tmp->pub.chain_signal,
|
|
||||||
IEEE80211_MAX_CHAINS);
|
|
||||||
ether_addr_copy(found->parent_bssid, tmp->parent_bssid);
|
|
||||||
found->pub.max_bssid_indicator = tmp->pub.max_bssid_indicator;
|
|
||||||
found->pub.bssid_index = tmp->pub.bssid_index;
|
|
||||||
} else {
|
} else {
|
||||||
struct cfg80211_internal_bss *new;
|
struct cfg80211_internal_bss *new;
|
||||||
struct cfg80211_internal_bss *hidden;
|
struct cfg80211_internal_bss *hidden;
|
||||||
|
|||||||
Reference in New Issue
Block a user