aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh_hwmp.c
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2011-08-09 19:45:08 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-24 13:59:42 -0400
commit5ee68e5b39de5cefecf147c58711f8ab01c21231 (patch)
tree59a39c4dc5a38497aa786689552136d95c690ecf /net/mac80211/mesh_hwmp.c
parent00e3f25c8556384bfec2a168c41e885fa6a7748c (diff)
mac80211: mesh gate implementation
In this implementation, a mesh gate is a root node with a certain bit set in its RANN flags. The mpath to this root node is marked as a path to a gate, and added to our list of known gates for this if_mesh. Once a path discovery process fails, we forward the unresolved frames to a known gate. Thanks to Luis Rodriguez for refactoring and bug fix help. Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mesh_hwmp.c')
-rw-r--r--net/mac80211/mesh_hwmp.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index abd03473cca4..7b517c46100d 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -696,6 +696,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
696 u8 *orig_addr; 696 u8 *orig_addr;
697 u32 orig_sn, metric; 697 u32 orig_sn, metric;
698 u32 interval = cpu_to_le32(IEEE80211_MESH_RANN_INTERVAL); 698 u32 interval = cpu_to_le32(IEEE80211_MESH_RANN_INTERVAL);
699 bool root_is_gate;
699 700
700 ttl = rann->rann_ttl; 701 ttl = rann->rann_ttl;
701 if (ttl <= 1) { 702 if (ttl <= 1) {
@@ -704,12 +705,19 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
704 } 705 }
705 ttl--; 706 ttl--;
706 flags = rann->rann_flags; 707 flags = rann->rann_flags;
708 root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
707 orig_addr = rann->rann_addr; 709 orig_addr = rann->rann_addr;
708 orig_sn = rann->rann_seq; 710 orig_sn = rann->rann_seq;
709 hopcount = rann->rann_hopcount; 711 hopcount = rann->rann_hopcount;
710 hopcount++; 712 hopcount++;
711 metric = rann->rann_metric; 713 metric = rann->rann_metric;
712 mhwmp_dbg("received RANN from %pM\n", orig_addr); 714
715 /* Ignore our own RANNs */
716 if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
717 return;
718
719 mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr,
720 root_is_gate);
713 721
714 rcu_read_lock(); 722 rcu_read_lock();
715 mpath = mesh_path_lookup(orig_addr, sdata); 723 mpath = mesh_path_lookup(orig_addr, sdata);
@@ -721,9 +729,16 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
721 sdata->u.mesh.mshstats.dropped_frames_no_route++; 729 sdata->u.mesh.mshstats.dropped_frames_no_route++;
722 return; 730 return;
723 } 731 }
724 mesh_queue_preq(mpath,
725 PREQ_Q_F_START | PREQ_Q_F_REFRESH);
726 } 732 }
733
734 if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
735 time_after(jiffies, mpath->exp_time - 1*HZ)) &&
736 !(mpath->flags & MESH_PATH_FIXED)) {
737 mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name,
738 orig_addr);
739 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
740 }
741
727 if (mpath->sn < orig_sn) { 742 if (mpath->sn < orig_sn) {
728 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, 743 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
729 cpu_to_le32(orig_sn), 744 cpu_to_le32(orig_sn),
@@ -733,6 +748,9 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
733 0, sdata); 748 0, sdata);
734 mpath->sn = orig_sn; 749 mpath->sn = orig_sn;
735 } 750 }
751 if (root_is_gate)
752 mesh_path_add_gate(mpath);
753
736 rcu_read_unlock(); 754 rcu_read_unlock();
737} 755}
738 756
@@ -994,25 +1012,32 @@ void mesh_path_timer(unsigned long data)
994{ 1012{
995 struct mesh_path *mpath = (void *) data; 1013 struct mesh_path *mpath = (void *) data;
996 struct ieee80211_sub_if_data *sdata = mpath->sdata; 1014 struct ieee80211_sub_if_data *sdata = mpath->sdata;
1015 int ret;
997 1016
998 if (sdata->local->quiescing) 1017 if (sdata->local->quiescing)
999 return; 1018 return;
1000 1019
1001 spin_lock_bh(&mpath->state_lock); 1020 spin_lock_bh(&mpath->state_lock);
1002 if (mpath->flags & MESH_PATH_RESOLVED || 1021 if (mpath->flags & MESH_PATH_RESOLVED ||
1003 (!(mpath->flags & MESH_PATH_RESOLVING))) 1022 (!(mpath->flags & MESH_PATH_RESOLVING))) {
1004 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED); 1023 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED);
1005 else if (mpath->discovery_retries < max_preq_retries(sdata)) { 1024 spin_unlock_bh(&mpath->state_lock);
1025 } else if (mpath->discovery_retries < max_preq_retries(sdata)) {
1006 ++mpath->discovery_retries; 1026 ++mpath->discovery_retries;
1007 mpath->discovery_timeout *= 2; 1027 mpath->discovery_timeout *= 2;
1028 spin_unlock_bh(&mpath->state_lock);
1008 mesh_queue_preq(mpath, 0); 1029 mesh_queue_preq(mpath, 0);
1009 } else { 1030 } else {
1010 mpath->flags = 0; 1031 mpath->flags = 0;
1011 mpath->exp_time = jiffies; 1032 mpath->exp_time = jiffies;
1012 mesh_path_flush_pending(mpath); 1033 spin_unlock_bh(&mpath->state_lock);
1034 if (!mpath->is_gate && mesh_gate_num(sdata) > 0) {
1035 ret = mesh_path_send_to_gates(mpath);
1036 if (ret)
1037 mhwmp_dbg("no gate was reachable");
1038 } else
1039 mesh_path_flush_pending(mpath);
1013 } 1040 }
1014
1015 spin_unlock_bh(&mpath->state_lock);
1016} 1041}
1017 1042
1018void 1043void