aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh_hwmp.c
diff options
context:
space:
mode:
authorJesse Jones <jjones@cococorp.com>2015-06-12 18:38:07 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-07-17 09:38:16 -0400
commitd8f0300a7aca5cd9208112104c64d894ad82da1f (patch)
tree8078472b2dee3275704eb6fb1165fbb6c27bfe6a /net/mac80211/mesh_hwmp.c
parentd82547106ff9dee43e6ee4f4b3d70b5314ae266f (diff)
mac80211: mac80211: Check SN for deactivated mpaths
When processing a PREQ or PREP it's critical to use the incoming SN. If that is improperly done routing loops and other types of badness can happen. But the code was always processing path messages for deactivated paths. This path fixes that so that if we have a valid SN then we use it to verify that it is a message we can accept. For reference the relevant section of the standard is 13.10.8.4 which doesn't address the deactivated path case at all. I also included a special case for when our peer reboots or restarts networking. This is an important case because without it there can be a very long delay before we accept path messages from that peer. It's also a simple case and intimately associated with processing messages for deactivated paths so I used one patch instead of two. Signed-off-by: Alexis Green <agreen@cococorp.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mesh_hwmp.c')
-rw-r--r--net/mac80211/mesh_hwmp.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 5ed38c5a998f..f053213e5adb 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -79,6 +79,12 @@ static inline u16 u16_field_get(const u8 *preq_elem, int offset, bool ae)
79#define MSEC_TO_TU(x) (x*1000/1024) 79#define MSEC_TO_TU(x) (x*1000/1024)
80#define SN_GT(x, y) ((s32)(y - x) < 0) 80#define SN_GT(x, y) ((s32)(y - x) < 0)
81#define SN_LT(x, y) ((s32)(x - y) < 0) 81#define SN_LT(x, y) ((s32)(x - y) < 0)
82#define MAX_SANE_SN_DELTA 32
83
84static inline u32 SN_DELTA(u32 x, u32 y)
85{
86 return x >= y ? x - y : y - x;
87}
82 88
83#define net_traversal_jiffies(s) \ 89#define net_traversal_jiffies(s) \
84 msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime) 90 msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime)
@@ -441,6 +447,26 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
441 process = false; 447 process = false;
442 fresh_info = false; 448 fresh_info = false;
443 } 449 }
450 } else if (!(mpath->flags & MESH_PATH_ACTIVE)) {
451 bool have_sn, newer_sn, bounced;
452
453 have_sn = mpath->flags & MESH_PATH_SN_VALID;
454 newer_sn = have_sn && SN_GT(orig_sn, mpath->sn);
455 bounced = have_sn &&
456 (SN_DELTA(orig_sn, mpath->sn) >
457 MAX_SANE_SN_DELTA);
458
459 if (!have_sn || newer_sn) {
460 /* if SN is newer than what we had
461 * then we can take it */;
462 } else if (bounced) {
463 /* if SN is way different than what
464 * we had then assume the other side
465 * rebooted or restarted */;
466 } else {
467 process = false;
468 fresh_info = false;
469 }
444 } 470 }
445 } else { 471 } else {
446 mpath = mesh_path_add(sdata, orig_addr); 472 mpath = mesh_path_add(sdata, orig_addr);