aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@gmail.com>2009-11-09 18:46:56 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-13 17:43:56 -0500
commite304bfd30f356f7b75d30cad0029ecca705fd590 (patch)
tree64b466a5d6b70dba13605d5ec1ae656801caa212 /net
parentd19b3bf6384e66ac6e11a61ee31ed2cfe149f4d8 (diff)
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>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mesh.c39
-rw-r--r--net/mac80211/mesh.h3
-rw-r--r--net/mac80211/mesh_hwmp.c11
4 files changed, 54 insertions, 0 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index fb54ddb9b27d..b63b99fb2fd3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -355,6 +355,7 @@ struct ieee80211_if_mesh {
355 struct work_struct work; 355 struct work_struct work;
356 struct timer_list housekeeping_timer; 356 struct timer_list housekeeping_timer;
357 struct timer_list mesh_path_timer; 357 struct timer_list mesh_path_timer;
358 struct timer_list mesh_path_root_timer;
358 struct sk_buff_head skb_queue; 359 struct sk_buff_head skb_queue;
359 360
360 unsigned long timers_running; 361 unsigned long timers_running;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 0f3e1147ec4f..88dcfe3030b1 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -14,6 +14,7 @@
14 14
15#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) 15#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
16#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) 16#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
17#define IEEE80211_MESH_RANN_INTERVAL (1 * HZ)
17 18
18#define MESHCONF_PP_OFFSET 0 /* Path Selection Protocol */ 19#define MESHCONF_PP_OFFSET 0 /* Path Selection Protocol */
19#define MESHCONF_PM_OFFSET 1 /* Path Selection Metric */ 20#define MESHCONF_PM_OFFSET 1 /* Path Selection Metric */
@@ -26,6 +27,7 @@
26 27
27#define TMR_RUNNING_HK 0 28#define TMR_RUNNING_HK 0
28#define TMR_RUNNING_MP 1 29#define TMR_RUNNING_MP 1
30#define TMR_RUNNING_MPR 2
29 31
30int mesh_allocated; 32int mesh_allocated;
31static struct kmem_cache *rm_cache; 33static struct kmem_cache *rm_cache;
@@ -354,6 +356,23 @@ static void ieee80211_mesh_path_timer(unsigned long data)
354 ieee80211_queue_work(&local->hw, &ifmsh->work); 356 ieee80211_queue_work(&local->hw, &ifmsh->work);
355} 357}
356 358
359static void ieee80211_mesh_path_root_timer(unsigned long data)
360{
361 struct ieee80211_sub_if_data *sdata =
362 (struct ieee80211_sub_if_data *) data;
363 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
364 struct ieee80211_local *local = sdata->local;
365
366 set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
367
368 if (local->quiescing) {
369 set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
370 return;
371 }
372
373 ieee80211_queue_work(&local->hw, &ifmsh->work);
374}
375
357/** 376/**
358 * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame 377 * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
359 * @hdr: 802.11 frame header 378 * @hdr: 802.11 frame header
@@ -447,6 +466,15 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
447 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); 466 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
448} 467}
449 468
469static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
470{
471 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
472
473 mesh_path_tx_root_frame(sdata);
474 mod_timer(&ifmsh->mesh_path_root_timer,
475 round_jiffies(jiffies + IEEE80211_MESH_RANN_INTERVAL));
476}
477
450#ifdef CONFIG_PM 478#ifdef CONFIG_PM
451void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) 479void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
452{ 480{
@@ -461,6 +489,8 @@ void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
461 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); 489 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
462 if (del_timer_sync(&ifmsh->mesh_path_timer)) 490 if (del_timer_sync(&ifmsh->mesh_path_timer))
463 set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); 491 set_bit(TMR_RUNNING_MP, &ifmsh->timers_running);
492 if (del_timer_sync(&ifmsh->mesh_path_root_timer))
493 set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
464} 494}
465 495
466void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata) 496void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
@@ -471,6 +501,8 @@ void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
471 add_timer(&ifmsh->housekeeping_timer); 501 add_timer(&ifmsh->housekeeping_timer);
472 if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running)) 502 if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running))
473 add_timer(&ifmsh->mesh_path_timer); 503 add_timer(&ifmsh->mesh_path_timer);
504 if (test_and_clear_bit(TMR_RUNNING_MPR, &ifmsh->timers_running))
505 add_timer(&ifmsh->mesh_path_root_timer);
474} 506}
475#endif 507#endif
476 508
@@ -490,6 +522,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
490void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) 522void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
491{ 523{
492 del_timer_sync(&sdata->u.mesh.housekeeping_timer); 524 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
525 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
493 /* 526 /*
494 * If the timer fired while we waited for it, it will have 527 * If the timer fired while we waited for it, it will have
495 * requeued the work. Now the work will be running again 528 * requeued the work. Now the work will be running again
@@ -627,6 +660,9 @@ static void ieee80211_mesh_work(struct work_struct *work)
627 660
628 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) 661 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
629 ieee80211_mesh_housekeeping(sdata, ifmsh); 662 ieee80211_mesh_housekeeping(sdata, ifmsh);
663
664 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags))
665 ieee80211_mesh_rootpath(sdata);
630} 666}
631 667
632void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) 668void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
@@ -683,6 +719,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
683 setup_timer(&ifmsh->mesh_path_timer, 719 setup_timer(&ifmsh->mesh_path_timer,
684 ieee80211_mesh_path_timer, 720 ieee80211_mesh_path_timer,
685 (unsigned long) sdata); 721 (unsigned long) sdata);
722 setup_timer(&ifmsh->mesh_path_root_timer,
723 ieee80211_mesh_path_root_timer,
724 (unsigned long) sdata);
686 INIT_LIST_HEAD(&ifmsh->preq_queue.list); 725 INIT_LIST_HEAD(&ifmsh->preq_queue.list);
687 spin_lock_init(&ifmsh->mesh_preq_queue_lock); 726 spin_lock_init(&ifmsh->mesh_preq_queue_lock);
688} 727}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index ee687add3927..00ee84258196 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -53,11 +53,13 @@ enum mesh_path_flags {
53 * to grow. 53 * to grow.
54 * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to 54 * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
55 * grow 55 * grow
56 * @MESH_WORK_ROOT: the mesh root station needs to send a frame
56 */ 57 */
57enum mesh_deferred_task_flags { 58enum mesh_deferred_task_flags {
58 MESH_WORK_HOUSEKEEPING, 59 MESH_WORK_HOUSEKEEPING,
59 MESH_WORK_GROW_MPATH_TABLE, 60 MESH_WORK_GROW_MPATH_TABLE,
60 MESH_WORK_GROW_MPP_TABLE, 61 MESH_WORK_GROW_MPP_TABLE,
62 MESH_WORK_ROOT,
61}; 63};
62 64
63/** 65/**
@@ -294,6 +296,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
294 struct ieee80211_sub_if_data *sdata); 296 struct ieee80211_sub_if_data *sdata);
295void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); 297void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
296void mesh_path_restart(struct ieee80211_sub_if_data *sdata); 298void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
299void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
297 300
298extern int mesh_paths_generation; 301extern int mesh_paths_generation;
299 302
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index f03a27dfd616..7483894a3960 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1003,3 +1003,14 @@ void mesh_path_timer(unsigned long data)
1003endmpathtimer: 1003endmpathtimer:
1004 rcu_read_unlock(); 1004 rcu_read_unlock();
1005} 1005}
1006
1007void
1008mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1009{
1010 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1011
1012 mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->dev->dev_addr,
1013 cpu_to_le32(++ifmsh->sn),
1014 0, NULL, 0, sdata->dev->broadcast,
1015 0, MESH_TTL, 0, 0, 0, sdata);
1016}