aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh_hwmp.c
diff options
context:
space:
mode:
authorChun-Yeow Yeoh <yeohchunyeow@gmail.com>2012-06-16 14:27:40 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-06-18 07:54:38 -0400
commit3fbf4b71be81e6dd3d6bfbcdef9618628ee1bafe (patch)
tree3daa90c5323eb67f1442371491c15b2baee2d277 /net/mac80211/mesh_hwmp.c
parenta69cc44fe9ebb806c5f3f8bd83fb4a50ca63647b (diff)
mac80211: implement the proactive PREP generation
Generate the proactive PREP element in Proactive PREQ mode as defined in Sec. 13.10.10.3 (Case D) of IEEE Std. 802.11-2012. Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@gmail.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.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index a6b08f5c461..35e3acbe226 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -516,10 +516,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
516 struct mesh_path *mpath = NULL; 516 struct mesh_path *mpath = NULL;
517 u8 *target_addr, *orig_addr; 517 u8 *target_addr, *orig_addr;
518 const u8 *da; 518 const u8 *da;
519 u8 target_flags, ttl; 519 u8 target_flags, ttl, flags;
520 u32 orig_sn, target_sn, lifetime; 520 u32 orig_sn, target_sn, lifetime, orig_metric;
521 bool reply = false; 521 bool reply = false;
522 bool forward = true; 522 bool forward = true;
523 bool root_is_gate;
523 524
524 /* Update target SN, if present */ 525 /* Update target SN, if present */
525 target_addr = PREQ_IE_TARGET_ADDR(preq_elem); 526 target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
@@ -527,6 +528,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
527 target_sn = PREQ_IE_TARGET_SN(preq_elem); 528 target_sn = PREQ_IE_TARGET_SN(preq_elem);
528 orig_sn = PREQ_IE_ORIG_SN(preq_elem); 529 orig_sn = PREQ_IE_ORIG_SN(preq_elem);
529 target_flags = PREQ_IE_TARGET_F(preq_elem); 530 target_flags = PREQ_IE_TARGET_F(preq_elem);
531 orig_metric = metric;
532 /* Proactive PREQ gate announcements */
533 flags = PREQ_IE_FLAGS(preq_elem);
534 root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
530 535
531 mhwmp_dbg("received PREQ from %pM", orig_addr); 536 mhwmp_dbg("received PREQ from %pM", orig_addr);
532 537
@@ -541,6 +546,22 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
541 target_sn = ++ifmsh->sn; 546 target_sn = ++ifmsh->sn;
542 ifmsh->last_sn_update = jiffies; 547 ifmsh->last_sn_update = jiffies;
543 } 548 }
549 } else if (is_broadcast_ether_addr(target_addr) &&
550 (target_flags & IEEE80211_PREQ_TO_FLAG)) {
551 rcu_read_lock();
552 mpath = mesh_path_lookup(orig_addr, sdata);
553 if (mpath) {
554 if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
555 reply = true;
556 target_addr = sdata->vif.addr;
557 target_sn = ++ifmsh->sn;
558 metric = 0;
559 ifmsh->last_sn_update = jiffies;
560 }
561 if (root_is_gate)
562 mesh_path_add_gate(mpath);
563 }
564 rcu_read_unlock();
544 } else { 565 } else {
545 rcu_read_lock(); 566 rcu_read_lock();
546 mpath = mesh_path_lookup(target_addr, sdata); 567 mpath = mesh_path_lookup(target_addr, sdata);
@@ -573,13 +594,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
573 cpu_to_le32(target_sn), mgmt->sa, 0, ttl, 594 cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
574 cpu_to_le32(lifetime), cpu_to_le32(metric), 595 cpu_to_le32(lifetime), cpu_to_le32(metric),
575 0, sdata); 596 0, sdata);
576 } else 597 } else {
577 ifmsh->mshstats.dropped_frames_ttl++; 598 ifmsh->mshstats.dropped_frames_ttl++;
599 }
578 } 600 }
579 601
580 if (forward && ifmsh->mshcfg.dot11MeshForwarding) { 602 if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
581 u32 preq_id; 603 u32 preq_id;
582 u8 hopcount, flags; 604 u8 hopcount;
583 605
584 ttl = PREQ_IE_TTL(preq_elem); 606 ttl = PREQ_IE_TTL(preq_elem);
585 lifetime = PREQ_IE_LIFETIME(preq_elem); 607 lifetime = PREQ_IE_LIFETIME(preq_elem);
@@ -589,11 +611,17 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
589 } 611 }
590 mhwmp_dbg("forwarding the PREQ from %pM", orig_addr); 612 mhwmp_dbg("forwarding the PREQ from %pM", orig_addr);
591 --ttl; 613 --ttl;
592 flags = PREQ_IE_FLAGS(preq_elem);
593 preq_id = PREQ_IE_PREQ_ID(preq_elem); 614 preq_id = PREQ_IE_PREQ_ID(preq_elem);
594 hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; 615 hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
595 da = (mpath && mpath->is_root) ? 616 da = (mpath && mpath->is_root) ?
596 mpath->rann_snd_addr : broadcast_addr; 617 mpath->rann_snd_addr : broadcast_addr;
618
619 if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
620 target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
621 target_sn = PREQ_IE_TARGET_SN(preq_elem);
622 metric = orig_metric;
623 }
624
597 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, 625 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
598 cpu_to_le32(orig_sn), target_flags, target_addr, 626 cpu_to_le32(orig_sn), target_flags, target_addr,
599 cpu_to_le32(target_sn), da, 627 cpu_to_le32(target_sn), da,