Commit 6f89ecf1 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'mac80211-for-net-2022-01-04' of...

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.netSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7d18a078 8b5cb7e4
...@@ -647,6 +647,26 @@ struct mesh_csa_settings { ...@@ -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 { ...@@ -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 { ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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);
......
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