Two more changes:
* mac80211: initialize a variable to avoid using it uninitialized * mac80211 mesh: put some data structures into the container to fix bugs with and not have to deal with allocation failures -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAmHUXRsACgkQB8qZga/f l8SsTA/+LlIv/c4HLaRP5t42ybDqTyAS02rGsMKxadb0kUUTyyByvMrIEbp36vXb Lc4ZvnWtweRrE0issn/FOMKi7g2iTVwNMo0xlUStZAO+hOVf1PK6KMCLNs4gZlvj VKrQQaTVwnAAcdniNNSc3LxHC2h1IEc3D7ITS23mrfLL+mKFji+jzAWGwQgyKrZh MeRLaYCvsAeaVxshYcJjeFJ/NYf8GjNmSYJNyatq8nXzIwRYrTON294x7QX+EDQ3 raGsD0ihYvOO0Lfji5YoQEVSjW/ePzRGJGMbtwmpLh1TwPSXAKbS8mz1skg2TqoB 9DAQyYFa/6pa15S0uQkvf5pf9cqvQJyCmSsy97WaLZBPjYfCHRXMYIlSpW49aVv/ b5Wkxxh30AXRA/Xj2gi5jb9JIyE3/awO3mmjF3l10d/NAyChtMqpxJrOfd7aWo3n EhQlC71CMPYlMcKDhAs9NXesa/R3EqnjhYHSqcOX/yyd3xZ7MV5F3J7DTDDDJLsR a6eD2rPCgM7lFIfiiDTlqP+oOwBTojyXuImsBsTW+SObCXJtkClykD1h5BEUg8ca Y5hkl/2Pyes6x3UGCrccviOyFcWrSNxW6Di+du/t6R7tnaKJd0/xSDB/s8cnILsn r97Ww70DX4MqrAMPCdIeRCXf4czquqknPuDTt3DgnvKxJZnkl7c= =eiG1 -----END PGP SIGNATURE----- Merge tag 'mac80211-for-net-2022-01-04' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211 Johannes Berg says: ==================== Two more changes: - mac80211: initialize a variable to avoid using it uninitialized - mac80211 mesh: put some data structures into the container to fix bugs with and not have to deal with allocation failures * tag 'mac80211-for-net-2022-01-04' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211: mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh mac80211: initialize variable have_higher_than_11mbit ==================== Link: https://lore.kernel.org/r/20220104144449.64937-1-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
6f89ecf10a
@ -647,6 +647,26 @@ struct mesh_csa_settings {
|
|||||||
struct cfg80211_csa_settings settings;
|
struct cfg80211_csa_settings settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mesh_table
|
||||||
|
*
|
||||||
|
* @known_gates: list of known mesh gates and their mpaths by the station. The
|
||||||
|
* gate's mpath may or may not be resolved and active.
|
||||||
|
* @gates_lock: protects updates to known_gates
|
||||||
|
* @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr
|
||||||
|
* @walk_head: linked list containing all mesh_path objects
|
||||||
|
* @walk_lock: lock protecting walk_head
|
||||||
|
* @entries: number of entries in the table
|
||||||
|
*/
|
||||||
|
struct mesh_table {
|
||||||
|
struct hlist_head known_gates;
|
||||||
|
spinlock_t gates_lock;
|
||||||
|
struct rhashtable rhead;
|
||||||
|
struct hlist_head walk_head;
|
||||||
|
spinlock_t walk_lock;
|
||||||
|
atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */
|
||||||
|
};
|
||||||
|
|
||||||
struct ieee80211_if_mesh {
|
struct ieee80211_if_mesh {
|
||||||
struct timer_list housekeeping_timer;
|
struct timer_list housekeeping_timer;
|
||||||
struct timer_list mesh_path_timer;
|
struct timer_list mesh_path_timer;
|
||||||
@ -721,8 +741,8 @@ struct ieee80211_if_mesh {
|
|||||||
/* offset from skb->data while building IE */
|
/* offset from skb->data while building IE */
|
||||||
int meshconf_offset;
|
int meshconf_offset;
|
||||||
|
|
||||||
struct mesh_table *mesh_paths;
|
struct mesh_table mesh_paths;
|
||||||
struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */
|
struct mesh_table mpp_paths; /* Store paths for MPP&MAP */
|
||||||
int mesh_paths_generation;
|
int mesh_paths_generation;
|
||||||
int mpp_paths_generation;
|
int mpp_paths_generation;
|
||||||
};
|
};
|
||||||
|
@ -127,26 +127,6 @@ struct mesh_path {
|
|||||||
u32 path_change_count;
|
u32 path_change_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct mesh_table
|
|
||||||
*
|
|
||||||
* @known_gates: list of known mesh gates and their mpaths by the station. The
|
|
||||||
* gate's mpath may or may not be resolved and active.
|
|
||||||
* @gates_lock: protects updates to known_gates
|
|
||||||
* @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr
|
|
||||||
* @walk_head: linked list containing all mesh_path objects
|
|
||||||
* @walk_lock: lock protecting walk_head
|
|
||||||
* @entries: number of entries in the table
|
|
||||||
*/
|
|
||||||
struct mesh_table {
|
|
||||||
struct hlist_head known_gates;
|
|
||||||
spinlock_t gates_lock;
|
|
||||||
struct rhashtable rhead;
|
|
||||||
struct hlist_head walk_head;
|
|
||||||
spinlock_t walk_lock;
|
|
||||||
atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Recent multicast cache */
|
/* Recent multicast cache */
|
||||||
/* RMC_BUCKETS must be a power of 2, maximum 256 */
|
/* RMC_BUCKETS must be a power of 2, maximum 256 */
|
||||||
#define RMC_BUCKETS 256
|
#define RMC_BUCKETS 256
|
||||||
@ -308,7 +288,7 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
|
|||||||
void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
|
void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
|
||||||
void mesh_path_flush_pending(struct mesh_path *mpath);
|
void mesh_path_flush_pending(struct mesh_path *mpath);
|
||||||
void mesh_path_tx_pending(struct mesh_path *mpath);
|
void mesh_path_tx_pending(struct mesh_path *mpath);
|
||||||
int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata);
|
void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata);
|
||||||
void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata);
|
void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata);
|
||||||
int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr);
|
int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr);
|
||||||
void mesh_path_timer(struct timer_list *t);
|
void mesh_path_timer(struct timer_list *t);
|
||||||
|
@ -47,32 +47,24 @@ static void mesh_path_rht_free(void *ptr, void *tblptr)
|
|||||||
mesh_path_free_rcu(tbl, mpath);
|
mesh_path_free_rcu(tbl, mpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mesh_table *mesh_table_alloc(void)
|
static void mesh_table_init(struct mesh_table *tbl)
|
||||||
{
|
{
|
||||||
struct mesh_table *newtbl;
|
INIT_HLIST_HEAD(&tbl->known_gates);
|
||||||
|
INIT_HLIST_HEAD(&tbl->walk_head);
|
||||||
|
atomic_set(&tbl->entries, 0);
|
||||||
|
spin_lock_init(&tbl->gates_lock);
|
||||||
|
spin_lock_init(&tbl->walk_lock);
|
||||||
|
|
||||||
newtbl = kmalloc(sizeof(struct mesh_table), GFP_ATOMIC);
|
/* rhashtable_init() may fail only in case of wrong
|
||||||
if (!newtbl)
|
* mesh_rht_params
|
||||||
return NULL;
|
*/
|
||||||
|
WARN_ON(rhashtable_init(&tbl->rhead, &mesh_rht_params));
|
||||||
INIT_HLIST_HEAD(&newtbl->known_gates);
|
|
||||||
INIT_HLIST_HEAD(&newtbl->walk_head);
|
|
||||||
atomic_set(&newtbl->entries, 0);
|
|
||||||
spin_lock_init(&newtbl->gates_lock);
|
|
||||||
spin_lock_init(&newtbl->walk_lock);
|
|
||||||
if (rhashtable_init(&newtbl->rhead, &mesh_rht_params)) {
|
|
||||||
kfree(newtbl);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newtbl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mesh_table_free(struct mesh_table *tbl)
|
static void mesh_table_free(struct mesh_table *tbl)
|
||||||
{
|
{
|
||||||
rhashtable_free_and_destroy(&tbl->rhead,
|
rhashtable_free_and_destroy(&tbl->rhead,
|
||||||
mesh_path_rht_free, tbl);
|
mesh_path_rht_free, tbl);
|
||||||
kfree(tbl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -238,13 +230,13 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst,
|
|||||||
struct mesh_path *
|
struct mesh_path *
|
||||||
mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
|
mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
|
||||||
{
|
{
|
||||||
return mpath_lookup(sdata->u.mesh.mesh_paths, dst, sdata);
|
return mpath_lookup(&sdata->u.mesh.mesh_paths, dst, sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mesh_path *
|
struct mesh_path *
|
||||||
mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
|
mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
|
||||||
{
|
{
|
||||||
return mpath_lookup(sdata->u.mesh.mpp_paths, dst, sdata);
|
return mpath_lookup(&sdata->u.mesh.mpp_paths, dst, sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mesh_path *
|
static struct mesh_path *
|
||||||
@ -281,7 +273,7 @@ __mesh_path_lookup_by_idx(struct mesh_table *tbl, int idx)
|
|||||||
struct mesh_path *
|
struct mesh_path *
|
||||||
mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
|
mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
|
||||||
{
|
{
|
||||||
return __mesh_path_lookup_by_idx(sdata->u.mesh.mesh_paths, idx);
|
return __mesh_path_lookup_by_idx(&sdata->u.mesh.mesh_paths, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -296,7 +288,7 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
|
|||||||
struct mesh_path *
|
struct mesh_path *
|
||||||
mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
|
mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
|
||||||
{
|
{
|
||||||
return __mesh_path_lookup_by_idx(sdata->u.mesh.mpp_paths, idx);
|
return __mesh_path_lookup_by_idx(&sdata->u.mesh.mpp_paths, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -309,7 +301,7 @@ int mesh_path_add_gate(struct mesh_path *mpath)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
tbl = mpath->sdata->u.mesh.mesh_paths;
|
tbl = &mpath->sdata->u.mesh.mesh_paths;
|
||||||
|
|
||||||
spin_lock_bh(&mpath->state_lock);
|
spin_lock_bh(&mpath->state_lock);
|
||||||
if (mpath->is_gate) {
|
if (mpath->is_gate) {
|
||||||
@ -418,7 +410,7 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata,
|
|||||||
if (!new_mpath)
|
if (!new_mpath)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
tbl = sdata->u.mesh.mesh_paths;
|
tbl = &sdata->u.mesh.mesh_paths;
|
||||||
spin_lock_bh(&tbl->walk_lock);
|
spin_lock_bh(&tbl->walk_lock);
|
||||||
mpath = rhashtable_lookup_get_insert_fast(&tbl->rhead,
|
mpath = rhashtable_lookup_get_insert_fast(&tbl->rhead,
|
||||||
&new_mpath->rhash,
|
&new_mpath->rhash,
|
||||||
@ -460,7 +452,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
memcpy(new_mpath->mpp, mpp, ETH_ALEN);
|
memcpy(new_mpath->mpp, mpp, ETH_ALEN);
|
||||||
tbl = sdata->u.mesh.mpp_paths;
|
tbl = &sdata->u.mesh.mpp_paths;
|
||||||
|
|
||||||
spin_lock_bh(&tbl->walk_lock);
|
spin_lock_bh(&tbl->walk_lock);
|
||||||
ret = rhashtable_lookup_insert_fast(&tbl->rhead,
|
ret = rhashtable_lookup_insert_fast(&tbl->rhead,
|
||||||
@ -489,7 +481,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata,
|
|||||||
void mesh_plink_broken(struct sta_info *sta)
|
void mesh_plink_broken(struct sta_info *sta)
|
||||||
{
|
{
|
||||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||||
struct mesh_table *tbl = sdata->u.mesh.mesh_paths;
|
struct mesh_table *tbl = &sdata->u.mesh.mesh_paths;
|
||||||
static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
struct mesh_path *mpath;
|
struct mesh_path *mpath;
|
||||||
|
|
||||||
@ -548,7 +540,7 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath)
|
|||||||
void mesh_path_flush_by_nexthop(struct sta_info *sta)
|
void mesh_path_flush_by_nexthop(struct sta_info *sta)
|
||||||
{
|
{
|
||||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||||
struct mesh_table *tbl = sdata->u.mesh.mesh_paths;
|
struct mesh_table *tbl = &sdata->u.mesh.mesh_paths;
|
||||||
struct mesh_path *mpath;
|
struct mesh_path *mpath;
|
||||||
struct hlist_node *n;
|
struct hlist_node *n;
|
||||||
|
|
||||||
@ -563,7 +555,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
|
|||||||
static void mpp_flush_by_proxy(struct ieee80211_sub_if_data *sdata,
|
static void mpp_flush_by_proxy(struct ieee80211_sub_if_data *sdata,
|
||||||
const u8 *proxy)
|
const u8 *proxy)
|
||||||
{
|
{
|
||||||
struct mesh_table *tbl = sdata->u.mesh.mpp_paths;
|
struct mesh_table *tbl = &sdata->u.mesh.mpp_paths;
|
||||||
struct mesh_path *mpath;
|
struct mesh_path *mpath;
|
||||||
struct hlist_node *n;
|
struct hlist_node *n;
|
||||||
|
|
||||||
@ -597,8 +589,8 @@ static void table_flush_by_iface(struct mesh_table *tbl)
|
|||||||
*/
|
*/
|
||||||
void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
|
void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
table_flush_by_iface(sdata->u.mesh.mesh_paths);
|
table_flush_by_iface(&sdata->u.mesh.mesh_paths);
|
||||||
table_flush_by_iface(sdata->u.mesh.mpp_paths);
|
table_flush_by_iface(&sdata->u.mesh.mpp_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -644,7 +636,7 @@ int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
|
|||||||
/* flush relevant mpp entries first */
|
/* flush relevant mpp entries first */
|
||||||
mpp_flush_by_proxy(sdata, addr);
|
mpp_flush_by_proxy(sdata, addr);
|
||||||
|
|
||||||
err = table_path_del(sdata->u.mesh.mesh_paths, sdata, addr);
|
err = table_path_del(&sdata->u.mesh.mesh_paths, sdata, addr);
|
||||||
sdata->u.mesh.mesh_paths_generation++;
|
sdata->u.mesh.mesh_paths_generation++;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -682,7 +674,7 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
|
|||||||
struct mesh_path *gate;
|
struct mesh_path *gate;
|
||||||
bool copy = false;
|
bool copy = false;
|
||||||
|
|
||||||
tbl = sdata->u.mesh.mesh_paths;
|
tbl = &sdata->u.mesh.mesh_paths;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
hlist_for_each_entry_rcu(gate, &tbl->known_gates, gate_list) {
|
hlist_for_each_entry_rcu(gate, &tbl->known_gates, gate_list) {
|
||||||
@ -762,29 +754,10 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop)
|
|||||||
mesh_path_tx_pending(mpath);
|
mesh_path_tx_pending(mpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata)
|
void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
struct mesh_table *tbl_path, *tbl_mpp;
|
mesh_table_init(&sdata->u.mesh.mesh_paths);
|
||||||
int ret;
|
mesh_table_init(&sdata->u.mesh.mpp_paths);
|
||||||
|
|
||||||
tbl_path = mesh_table_alloc();
|
|
||||||
if (!tbl_path)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
tbl_mpp = mesh_table_alloc();
|
|
||||||
if (!tbl_mpp) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto free_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
sdata->u.mesh.mesh_paths = tbl_path;
|
|
||||||
sdata->u.mesh.mpp_paths = tbl_mpp;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
free_path:
|
|
||||||
mesh_table_free(tbl_path);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -806,12 +779,12 @@ void mesh_path_tbl_expire(struct ieee80211_sub_if_data *sdata,
|
|||||||
|
|
||||||
void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
|
void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
mesh_path_tbl_expire(sdata, sdata->u.mesh.mesh_paths);
|
mesh_path_tbl_expire(sdata, &sdata->u.mesh.mesh_paths);
|
||||||
mesh_path_tbl_expire(sdata, sdata->u.mesh.mpp_paths);
|
mesh_path_tbl_expire(sdata, &sdata->u.mesh.mpp_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata)
|
void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
mesh_table_free(sdata->u.mesh.mesh_paths);
|
mesh_table_free(&sdata->u.mesh.mesh_paths);
|
||||||
mesh_table_free(sdata->u.mesh.mpp_paths);
|
mesh_table_free(&sdata->u.mesh.mpp_paths);
|
||||||
}
|
}
|
||||||
|
@ -5265,7 +5265,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
|||||||
*/
|
*/
|
||||||
if (new_sta) {
|
if (new_sta) {
|
||||||
u32 rates = 0, basic_rates = 0;
|
u32 rates = 0, basic_rates = 0;
|
||||||
bool have_higher_than_11mbit;
|
bool have_higher_than_11mbit = false;
|
||||||
int min_rate = INT_MAX, min_rate_index = -1;
|
int min_rate = INT_MAX, min_rate_index = -1;
|
||||||
const struct cfg80211_bss_ies *ies;
|
const struct cfg80211_bss_ies *ies;
|
||||||
int shift = ieee80211_vif_get_shift(&sdata->vif);
|
int shift = ieee80211_vif_get_shift(&sdata->vif);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user