diff options
author | Javier Cardona <javier@cozybit.com> | 2011-08-09 19:45:08 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-08-24 13:59:42 -0400 |
commit | 5ee68e5b39de5cefecf147c58711f8ab01c21231 (patch) | |
tree | 59a39c4dc5a38497aa786689552136d95c690ecf /net/mac80211/mesh_hwmp.c | |
parent | 00e3f25c8556384bfec2a168c41e885fa6a7748c (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.c | 41 |
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 | ||
1018 | void | 1043 | void |