diff options
author | Chun-Yeow Yeoh <yeohchunyeow@gmail.com> | 2012-06-16 14:27:40 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-06-18 07:54:38 -0400 |
commit | 3fbf4b71be81e6dd3d6bfbcdef9618628ee1bafe (patch) | |
tree | 3daa90c5323eb67f1442371491c15b2baee2d277 /net | |
parent | a69cc44fe9ebb806c5f3f8bd83fb4a50ca63647b (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')
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index a6b08f5c4612..35e3acbe2262 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, |