mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 04:06:22 +00:00
mac80211: implement a timer to send RANN action frames
RANN (Root Annoucement) frame TX. Send an action frame every second trying to build a path to all nodes on the mesh. Signed-off-by: Rui Paulo <rpaulo@gmail.com> Signed-off-by: Javier Cardona <javier@cozybit.com> Reviewed-by: Andrey Yurovsky <andrey@cozybit.com> Tested-by: Brian Cavagnolo <brian@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
d19b3bf638
commit
e304bfd30f
4 changed files with 54 additions and 0 deletions
|
@ -355,6 +355,7 @@ struct ieee80211_if_mesh {
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
struct timer_list housekeeping_timer;
|
struct timer_list housekeeping_timer;
|
||||||
struct timer_list mesh_path_timer;
|
struct timer_list mesh_path_timer;
|
||||||
|
struct timer_list mesh_path_root_timer;
|
||||||
struct sk_buff_head skb_queue;
|
struct sk_buff_head skb_queue;
|
||||||
|
|
||||||
unsigned long timers_running;
|
unsigned long timers_running;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
|
#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
|
||||||
#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
|
#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
|
||||||
|
#define IEEE80211_MESH_RANN_INTERVAL (1 * HZ)
|
||||||
|
|
||||||
#define MESHCONF_PP_OFFSET 0 /* Path Selection Protocol */
|
#define MESHCONF_PP_OFFSET 0 /* Path Selection Protocol */
|
||||||
#define MESHCONF_PM_OFFSET 1 /* Path Selection Metric */
|
#define MESHCONF_PM_OFFSET 1 /* Path Selection Metric */
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
|
|
||||||
#define TMR_RUNNING_HK 0
|
#define TMR_RUNNING_HK 0
|
||||||
#define TMR_RUNNING_MP 1
|
#define TMR_RUNNING_MP 1
|
||||||
|
#define TMR_RUNNING_MPR 2
|
||||||
|
|
||||||
int mesh_allocated;
|
int mesh_allocated;
|
||||||
static struct kmem_cache *rm_cache;
|
static struct kmem_cache *rm_cache;
|
||||||
|
@ -354,6 +356,23 @@ static void ieee80211_mesh_path_timer(unsigned long data)
|
||||||
ieee80211_queue_work(&local->hw, &ifmsh->work);
|
ieee80211_queue_work(&local->hw, &ifmsh->work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ieee80211_mesh_path_root_timer(unsigned long data)
|
||||||
|
{
|
||||||
|
struct ieee80211_sub_if_data *sdata =
|
||||||
|
(struct ieee80211_sub_if_data *) data;
|
||||||
|
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||||
|
struct ieee80211_local *local = sdata->local;
|
||||||
|
|
||||||
|
set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
|
||||||
|
|
||||||
|
if (local->quiescing) {
|
||||||
|
set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ieee80211_queue_work(&local->hw, &ifmsh->work);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
|
* ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
|
||||||
* @hdr: 802.11 frame header
|
* @hdr: 802.11 frame header
|
||||||
|
@ -447,6 +466,15 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
|
||||||
round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
|
round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
|
||||||
|
{
|
||||||
|
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||||
|
|
||||||
|
mesh_path_tx_root_frame(sdata);
|
||||||
|
mod_timer(&ifmsh->mesh_path_root_timer,
|
||||||
|
round_jiffies(jiffies + IEEE80211_MESH_RANN_INTERVAL));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
|
void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
|
@ -461,6 +489,8 @@ void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
|
||||||
set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
|
set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
|
||||||
if (del_timer_sync(&ifmsh->mesh_path_timer))
|
if (del_timer_sync(&ifmsh->mesh_path_timer))
|
||||||
set_bit(TMR_RUNNING_MP, &ifmsh->timers_running);
|
set_bit(TMR_RUNNING_MP, &ifmsh->timers_running);
|
||||||
|
if (del_timer_sync(&ifmsh->mesh_path_root_timer))
|
||||||
|
set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
|
void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
|
||||||
|
@ -471,6 +501,8 @@ void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
|
||||||
add_timer(&ifmsh->housekeeping_timer);
|
add_timer(&ifmsh->housekeeping_timer);
|
||||||
if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running))
|
if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running))
|
||||||
add_timer(&ifmsh->mesh_path_timer);
|
add_timer(&ifmsh->mesh_path_timer);
|
||||||
|
if (test_and_clear_bit(TMR_RUNNING_MPR, &ifmsh->timers_running))
|
||||||
|
add_timer(&ifmsh->mesh_path_root_timer);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -490,6 +522,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
|
||||||
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
|
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
|
||||||
{
|
{
|
||||||
del_timer_sync(&sdata->u.mesh.housekeeping_timer);
|
del_timer_sync(&sdata->u.mesh.housekeeping_timer);
|
||||||
|
del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
|
||||||
/*
|
/*
|
||||||
* If the timer fired while we waited for it, it will have
|
* If the timer fired while we waited for it, it will have
|
||||||
* requeued the work. Now the work will be running again
|
* requeued the work. Now the work will be running again
|
||||||
|
@ -627,6 +660,9 @@ static void ieee80211_mesh_work(struct work_struct *work)
|
||||||
|
|
||||||
if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
|
if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
|
||||||
ieee80211_mesh_housekeeping(sdata, ifmsh);
|
ieee80211_mesh_housekeeping(sdata, ifmsh);
|
||||||
|
|
||||||
|
if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags))
|
||||||
|
ieee80211_mesh_rootpath(sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
|
void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
|
||||||
|
@ -683,6 +719,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
|
||||||
setup_timer(&ifmsh->mesh_path_timer,
|
setup_timer(&ifmsh->mesh_path_timer,
|
||||||
ieee80211_mesh_path_timer,
|
ieee80211_mesh_path_timer,
|
||||||
(unsigned long) sdata);
|
(unsigned long) sdata);
|
||||||
|
setup_timer(&ifmsh->mesh_path_root_timer,
|
||||||
|
ieee80211_mesh_path_root_timer,
|
||||||
|
(unsigned long) sdata);
|
||||||
INIT_LIST_HEAD(&ifmsh->preq_queue.list);
|
INIT_LIST_HEAD(&ifmsh->preq_queue.list);
|
||||||
spin_lock_init(&ifmsh->mesh_preq_queue_lock);
|
spin_lock_init(&ifmsh->mesh_preq_queue_lock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,11 +53,13 @@ enum mesh_path_flags {
|
||||||
* to grow.
|
* to grow.
|
||||||
* @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
|
* @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
|
||||||
* grow
|
* grow
|
||||||
|
* @MESH_WORK_ROOT: the mesh root station needs to send a frame
|
||||||
*/
|
*/
|
||||||
enum mesh_deferred_task_flags {
|
enum mesh_deferred_task_flags {
|
||||||
MESH_WORK_HOUSEKEEPING,
|
MESH_WORK_HOUSEKEEPING,
|
||||||
MESH_WORK_GROW_MPATH_TABLE,
|
MESH_WORK_GROW_MPATH_TABLE,
|
||||||
MESH_WORK_GROW_MPP_TABLE,
|
MESH_WORK_GROW_MPP_TABLE,
|
||||||
|
MESH_WORK_ROOT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -294,6 +296,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
|
||||||
struct ieee80211_sub_if_data *sdata);
|
struct ieee80211_sub_if_data *sdata);
|
||||||
void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
|
void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
|
||||||
void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
|
void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
|
||||||
|
void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
|
||||||
|
|
||||||
extern int mesh_paths_generation;
|
extern int mesh_paths_generation;
|
||||||
|
|
||||||
|
|
|
@ -1003,3 +1003,14 @@ void mesh_path_timer(unsigned long data)
|
||||||
endmpathtimer:
|
endmpathtimer:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
|
||||||
|
{
|
||||||
|
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||||
|
|
||||||
|
mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->dev->dev_addr,
|
||||||
|
cpu_to_le32(++ifmsh->sn),
|
||||||
|
0, NULL, 0, sdata->dev->broadcast,
|
||||||
|
0, MESH_TTL, 0, 0, 0, sdata);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue