Commit 7011ba58 authored by Sara Sharon's avatar Sara Sharon Committed by Johannes Berg

cfg80211: Move Multiple BSS info to struct cfg80211_bss to be visible

Previously the transmitted BSS and the non-trasmitted BSS list were
defined in struct cfg80211_internal_bss. Move them to struct cfg80211_bss
since mac80211 needs this info.
Signed-off-by: default avatarSara Sharon <sara.sharon@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent a3584f56
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2015-2017 Intel Deutschland GmbH * Copyright 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation * Copyright (C) 2018-2019 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -2049,6 +2049,8 @@ struct cfg80211_bss { ...@@ -2049,6 +2049,8 @@ struct cfg80211_bss {
const struct cfg80211_bss_ies __rcu *proberesp_ies; const struct cfg80211_bss_ies __rcu *proberesp_ies;
struct cfg80211_bss *hidden_beacon_bss; struct cfg80211_bss *hidden_beacon_bss;
struct cfg80211_bss *transmitted_bss;
struct list_head nontrans_list;
s32 signal; s32 signal;
......
...@@ -152,8 +152,6 @@ extern int cfg80211_rdev_list_generation; ...@@ -152,8 +152,6 @@ extern int cfg80211_rdev_list_generation;
struct cfg80211_internal_bss { struct cfg80211_internal_bss {
struct list_head list; struct list_head list;
struct list_head hidden_list; struct list_head hidden_list;
struct list_head nontrans_list;
struct cfg80211_bss *transmitted_bss;
struct rb_node rbn; struct rb_node rbn;
u64 ts_boottime; u64 ts_boottime;
unsigned long ts; unsigned long ts;
...@@ -184,8 +182,8 @@ static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pu ...@@ -184,8 +182,8 @@ static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pu
static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss) static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
{ {
atomic_inc(&bss->hold); atomic_inc(&bss->hold);
if (bss->transmitted_bss) { if (bss->pub.transmitted_bss) {
bss = container_of(bss->transmitted_bss, bss = container_of(bss->pub.transmitted_bss,
struct cfg80211_internal_bss, pub); struct cfg80211_internal_bss, pub);
atomic_inc(&bss->hold); atomic_inc(&bss->hold);
} }
...@@ -195,8 +193,8 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss) ...@@ -195,8 +193,8 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
{ {
int r = atomic_dec_return(&bss->hold); int r = atomic_dec_return(&bss->hold);
WARN_ON(r < 0); WARN_ON(r < 0);
if (bss->transmitted_bss) { if (bss->pub.transmitted_bss) {
bss = container_of(bss->transmitted_bss, bss = container_of(bss->pub.transmitted_bss,
struct cfg80211_internal_bss, pub); struct cfg80211_internal_bss, pub);
r = atomic_dec_return(&bss->hold); r = atomic_dec_return(&bss->hold);
WARN_ON(r < 0); WARN_ON(r < 0);
......
...@@ -110,8 +110,8 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev, ...@@ -110,8 +110,8 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
pub); pub);
bss->refcount++; bss->refcount++;
} }
if (bss->transmitted_bss) { if (bss->pub.transmitted_bss) {
bss = container_of(bss->transmitted_bss, bss = container_of(bss->pub.transmitted_bss,
struct cfg80211_internal_bss, struct cfg80211_internal_bss,
pub); pub);
bss->refcount++; bss->refcount++;
...@@ -133,10 +133,10 @@ static inline void bss_ref_put(struct cfg80211_registered_device *rdev, ...@@ -133,10 +133,10 @@ static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
bss_free(hbss); bss_free(hbss);
} }
if (bss->transmitted_bss) { if (bss->pub.transmitted_bss) {
struct cfg80211_internal_bss *tbss; struct cfg80211_internal_bss *tbss;
tbss = container_of(bss->transmitted_bss, tbss = container_of(bss->pub.transmitted_bss,
struct cfg80211_internal_bss, struct cfg80211_internal_bss,
pub); pub);
tbss->refcount--; tbss->refcount--;
...@@ -169,7 +169,7 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev, ...@@ -169,7 +169,7 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
} }
list_del_init(&bss->list); list_del_init(&bss->list);
list_del_init(&bss->nontrans_list); list_del_init(&bss->pub.nontrans_list);
rb_erase(&bss->rbn, &rdev->bss_tree); rb_erase(&bss->rbn, &rdev->bss_tree);
rdev->bss_entries--; rdev->bss_entries--;
WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list), WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list),
...@@ -317,15 +317,15 @@ static bool is_bss(struct cfg80211_bss *a, const u8 *bssid, ...@@ -317,15 +317,15 @@ static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
} }
static int static int
cfg80211_add_nontrans_list(struct cfg80211_internal_bss *trans_bss, cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
struct cfg80211_internal_bss *nontrans_bss) struct cfg80211_bss *nontrans_bss)
{ {
const u8 *ssid; const u8 *ssid;
size_t ssid_len; size_t ssid_len;
struct cfg80211_internal_bss *bss = NULL; struct cfg80211_bss *bss = NULL;
rcu_read_lock(); rcu_read_lock();
ssid = ieee80211_bss_get_ie(&nontrans_bss->pub, WLAN_EID_SSID); ssid = ieee80211_bss_get_ie(nontrans_bss, WLAN_EID_SSID);
if (!ssid) { if (!ssid) {
rcu_read_unlock(); rcu_read_unlock();
return -EINVAL; return -EINVAL;
...@@ -336,7 +336,7 @@ cfg80211_add_nontrans_list(struct cfg80211_internal_bss *trans_bss, ...@@ -336,7 +336,7 @@ cfg80211_add_nontrans_list(struct cfg80211_internal_bss *trans_bss,
/* check if nontrans_bss is in the list */ /* check if nontrans_bss is in the list */
list_for_each_entry(bss, &trans_bss->nontrans_list, nontrans_list) { list_for_each_entry(bss, &trans_bss->nontrans_list, nontrans_list) {
if (is_bss(&bss->pub, nontrans_bss->pub.bssid, ssid, ssid_len)) if (is_bss(bss, nontrans_bss->bssid, ssid, ssid_len))
return 0; return 0;
} }
...@@ -1166,7 +1166,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, ...@@ -1166,7 +1166,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
memcpy(new, tmp, sizeof(*new)); memcpy(new, tmp, sizeof(*new));
new->refcount = 1; new->refcount = 1;
INIT_LIST_HEAD(&new->hidden_list); INIT_LIST_HEAD(&new->hidden_list);
INIT_LIST_HEAD(&new->nontrans_list); INIT_LIST_HEAD(&new->pub.nontrans_list);
if (rcu_access_pointer(tmp->pub.proberesp_ies)) { if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN); hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
...@@ -1207,7 +1207,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, ...@@ -1207,7 +1207,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
struct cfg80211_internal_bss, struct cfg80211_internal_bss,
pub); pub);
new->transmitted_bss = trans_bss; new->pub.transmitted_bss = trans_bss;
bss_ref_get(rdev, pbss); bss_ref_get(rdev, pbss);
} }
...@@ -1311,7 +1311,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, ...@@ -1311,7 +1311,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct cfg80211_bss_ies *ies; struct cfg80211_bss_ies *ies;
struct ieee80211_channel *channel; struct ieee80211_channel *channel;
struct cfg80211_internal_bss tmp = {}, *res, *trans_internal; struct cfg80211_internal_bss tmp = {}, *res;
int bss_type; int bss_type;
bool signal_valid; bool signal_valid;
...@@ -1385,10 +1385,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, ...@@ -1385,10 +1385,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
/* this is a nontransmitting bss, we need to add it to /* this is a nontransmitting bss, we need to add it to
* transmitting bss' list if it is not there * transmitting bss' list if it is not there
*/ */
trans_internal = container_of(trans_bss, if (cfg80211_add_nontrans_list(trans_bss, &res->pub)) {
struct cfg80211_internal_bss,
pub);
if (cfg80211_add_nontrans_list(trans_internal, res)) {
if (__cfg80211_unlink_bss(rdev, res)) if (__cfg80211_unlink_bss(rdev, res))
rdev->bss_generation++; rdev->bss_generation++;
} }
...@@ -1523,7 +1520,7 @@ cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy, ...@@ -1523,7 +1520,7 @@ cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy,
static void static void
cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
struct cfg80211_internal_bss *nontrans_bss, struct cfg80211_bss *nontrans_bss,
struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_mgmt *mgmt, size_t len,
gfp_t gfp) gfp_t gfp)
{ {
...@@ -1548,7 +1545,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, ...@@ -1548,7 +1545,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
return; return;
new_ie_len -= mbssid[1]; new_ie_len -= mbssid[1];
rcu_read_lock(); rcu_read_lock();
nontrans_ssid = ieee80211_bss_get_ie(&nontrans_bss->pub, WLAN_EID_SSID); nontrans_ssid = ieee80211_bss_get_ie(nontrans_bss, WLAN_EID_SSID);
if (!nontrans_ssid) { if (!nontrans_ssid) {
rcu_read_unlock(); rcu_read_unlock();
return; return;
...@@ -1589,15 +1586,15 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, ...@@ -1589,15 +1586,15 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control); new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control);
memcpy(new_ies->data, new_ie, new_ie_len); memcpy(new_ies->data, new_ie, new_ie_len);
if (ieee80211_is_probe_resp(mgmt->frame_control)) { if (ieee80211_is_probe_resp(mgmt->frame_control)) {
old = rcu_access_pointer(nontrans_bss->pub.proberesp_ies); old = rcu_access_pointer(nontrans_bss->proberesp_ies);
rcu_assign_pointer(nontrans_bss->pub.proberesp_ies, new_ies); rcu_assign_pointer(nontrans_bss->proberesp_ies, new_ies);
rcu_assign_pointer(nontrans_bss->pub.ies, new_ies); rcu_assign_pointer(nontrans_bss->ies, new_ies);
if (old) if (old)
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
} else { } else {
old = rcu_access_pointer(nontrans_bss->pub.beacon_ies); old = rcu_access_pointer(nontrans_bss->beacon_ies);
rcu_assign_pointer(nontrans_bss->pub.beacon_ies, new_ies); rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
rcu_assign_pointer(nontrans_bss->pub.ies, new_ies); rcu_assign_pointer(nontrans_bss->ies, new_ies);
if (old) if (old)
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
} }
...@@ -1696,8 +1693,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, ...@@ -1696,8 +1693,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_mgmt *mgmt, size_t len,
gfp_t gfp) gfp_t gfp)
{ {
struct cfg80211_bss *res; struct cfg80211_bss *res, *tmp_bss;
struct cfg80211_internal_bss *trans_bss, *tmp_bss;
const u8 *ie = mgmt->u.probe_resp.variable; const u8 *ie = mgmt->u.probe_resp.variable;
const struct cfg80211_bss_ies *ies1, *ies2; const struct cfg80211_bss_ies *ies1, *ies2;
size_t ielen = len - offsetof(struct ieee80211_mgmt, size_t ielen = len - offsetof(struct ieee80211_mgmt,
...@@ -1715,17 +1711,14 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, ...@@ -1715,17 +1711,14 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
* in MBSSID IE * in MBSSID IE
*/ */
ies1 = rcu_access_pointer(res->ies); ies1 = rcu_access_pointer(res->ies);
trans_bss = container_of(res, struct cfg80211_internal_bss, pub);
if (!trans_bss)
return res;
/* go through nontrans_list, if the timestamp of the BSS is /* go through nontrans_list, if the timestamp of the BSS is
* earlier than the timestamp of the transmitting BSS then * earlier than the timestamp of the transmitting BSS then
* update it * update it
*/ */
list_for_each_entry(tmp_bss, &trans_bss->nontrans_list, list_for_each_entry(tmp_bss, &res->nontrans_list,
nontrans_list) { nontrans_list) {
ies2 = rcu_access_pointer(tmp_bss->pub.ies); ies2 = rcu_access_pointer(tmp_bss->ies);
if (ies2->tsf < ies1->tsf) if (ies2->tsf < ies1->tsf)
cfg80211_update_notlisted_nontrans(wiphy, tmp_bss, cfg80211_update_notlisted_nontrans(wiphy, tmp_bss,
mgmt, len, gfp); mgmt, len, gfp);
...@@ -1770,7 +1763,8 @@ EXPORT_SYMBOL(cfg80211_put_bss); ...@@ -1770,7 +1763,8 @@ EXPORT_SYMBOL(cfg80211_put_bss);
void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
{ {
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct cfg80211_internal_bss *bss, *nontrans_bss, *tmp; struct cfg80211_internal_bss *bss, *tmp1;
struct cfg80211_bss *nontrans_bss, *tmp;
if (WARN_ON(!pub)) if (WARN_ON(!pub))
return; return;
...@@ -1778,17 +1772,21 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) ...@@ -1778,17 +1772,21 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
bss = container_of(pub, struct cfg80211_internal_bss, pub); bss = container_of(pub, struct cfg80211_internal_bss, pub);
spin_lock_bh(&rdev->bss_lock); spin_lock_bh(&rdev->bss_lock);
if (!list_empty(&bss->list)) { if (list_empty(&bss->list))
goto out;
list_for_each_entry_safe(nontrans_bss, tmp, list_for_each_entry_safe(nontrans_bss, tmp,
&bss->nontrans_list, &pub->nontrans_list,
nontrans_list) { nontrans_list) {
if (__cfg80211_unlink_bss(rdev, nontrans_bss)) tmp1 = container_of(nontrans_bss,
struct cfg80211_internal_bss, pub);
if (__cfg80211_unlink_bss(rdev, tmp1))
rdev->bss_generation++; rdev->bss_generation++;
} }
if (__cfg80211_unlink_bss(rdev, bss)) if (__cfg80211_unlink_bss(rdev, bss))
rdev->bss_generation++; rdev->bss_generation++;
} out:
spin_unlock_bh(&rdev->bss_lock); spin_unlock_bh(&rdev->bss_lock);
} }
EXPORT_SYMBOL(cfg80211_unlink_bss); EXPORT_SYMBOL(cfg80211_unlink_bss);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment