aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@gmail.com>2009-11-09 18:46:46 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-11 15:23:58 -0500
commitdbb81c428bf534fcfe94102acca50f6d56504999 (patch)
tree9dcf3ddc9355eafe24293b4bd68db6560b37223a /net/mac80211
parent27db2e423fdeae8815087677261ab72cca7b3c28 (diff)
mac80211: allow processing of more than one HWMP IE
Since the HWMP IEs are now all optional and the action code is fixed, allow the HWMP code to find and process each IE on the path selection action frames. Signed-off-by: Rui Paulo <rpaulo@gmail.com> Signed-off-by: Javier Cardona <rpaulo@cozybit.com> Reviewed-by: Andrey Yurovsky <andrey@cozybit.com> Tested-by: Brian Cavagnolo <brian@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/mesh_hwmp.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 6dbaec53653d..e67e812f78e2 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -192,7 +192,7 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
192 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 192 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
193 /* BSSID is left zeroed, wildcard value */ 193 /* BSSID is left zeroed, wildcard value */
194 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 194 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY;
195 mgmt->u.action.u.mesh_action.action_code = MPATH_PERR; 195 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION;
196 ie_len = 12; 196 ie_len = 12;
197 pos = skb_put(skb, 2 + ie_len); 197 pos = skb_put(skb, 2 + ie_len);
198 *pos++ = WLAN_EID_PERR; 198 *pos++ = WLAN_EID_PERR;
@@ -277,7 +277,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
277 */ 277 */
278static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, 278static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
279 struct ieee80211_mgmt *mgmt, 279 struct ieee80211_mgmt *mgmt,
280 u8 *hwmp_ie) 280 u8 *hwmp_ie, enum mpath_frame_type action)
281{ 281{
282 struct ieee80211_local *local = sdata->local; 282 struct ieee80211_local *local = sdata->local;
283 struct mesh_path *mpath; 283 struct mesh_path *mpath;
@@ -288,7 +288,6 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
288 unsigned long orig_lifetime, exp_time; 288 unsigned long orig_lifetime, exp_time;
289 u32 last_hop_metric, new_metric; 289 u32 last_hop_metric, new_metric;
290 bool process = true; 290 bool process = true;
291 u8 action = mgmt->u.action.u.mesh_action.action_code;
292 291
293 rcu_read_lock(); 292 rcu_read_lock();
294 sta = sta_info_get(local, mgmt->sa); 293 sta = sta_info_get(local, mgmt->sa);
@@ -443,6 +442,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
443 mhwmp_dbg("received PREQ\n"); 442 mhwmp_dbg("received PREQ\n");
444 443
445 if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) { 444 if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) {
445 mhwmp_dbg("PREQ is for us\n");
446 forward = false; 446 forward = false;
447 reply = true; 447 reply = true;
448 metric = 0; 448 metric = 0;
@@ -498,6 +498,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
498 ifmsh->mshstats.dropped_frames_ttl++; 498 ifmsh->mshstats.dropped_frames_ttl++;
499 return; 499 return;
500 } 500 }
501 mhwmp_dbg("forwarding the PREQ\n");
501 --ttl; 502 --ttl;
502 flags = PREQ_IE_FLAGS(preq_elem); 503 flags = PREQ_IE_FLAGS(preq_elem);
503 preq_id = PREQ_IE_PREQ_ID(preq_elem); 504 preq_id = PREQ_IE_PREQ_ID(preq_elem);
@@ -524,6 +525,8 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
524 u8 next_hop[ETH_ALEN]; 525 u8 next_hop[ETH_ALEN];
525 u32 dst_dsn, orig_dsn, lifetime; 526 u32 dst_dsn, orig_dsn, lifetime;
526 527
528 mhwmp_dbg("received PREP\n");
529
527 /* Note that we divert from the draft nomenclature and denominate 530 /* Note that we divert from the draft nomenclature and denominate
528 * destination to what the draft refers to as origininator. So in this 531 * destination to what the draft refers to as origininator. So in this
529 * function destnation refers to the final destination of the PREP, 532 * function destnation refers to the final destination of the PREP,
@@ -625,32 +628,32 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
625 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, 628 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
626 len - baselen, &elems); 629 len - baselen, &elems);
627 630
628 switch (mgmt->u.action.u.mesh_action.action_code) { 631 mhwmp_dbg("RX path selection frame\n");
629 case MPATH_PREQ: 632 if (elems.preq) {
630 if (!elems.preq || elems.preq_len != 37) 633 if (elems.preq_len != 37)
631 /* Right now we support just 1 destination and no AE */ 634 /* Right now we support just 1 destination and no AE */
632 return; 635 return;
633 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.preq); 636 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.preq,
634 if (!last_hop_metric) 637 MPATH_PREQ);
635 return; 638 if (last_hop_metric)
636 hwmp_preq_frame_process(sdata, mgmt, elems.preq, last_hop_metric); 639 hwmp_preq_frame_process(sdata, mgmt, elems.preq,
637 break; 640 last_hop_metric);
638 case MPATH_PREP: 641 }
639 if (!elems.prep || elems.prep_len != 31) 642 if (elems.prep) {
643 if (elems.prep_len != 31)
640 /* Right now we support no AE */ 644 /* Right now we support no AE */
641 return; 645 return;
642 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.prep); 646 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.prep,
643 if (!last_hop_metric) 647 MPATH_PREP);
644 return; 648 if (last_hop_metric)
645 hwmp_prep_frame_process(sdata, mgmt, elems.prep, last_hop_metric); 649 hwmp_prep_frame_process(sdata, mgmt, elems.prep,
646 break; 650 last_hop_metric);
647 case MPATH_PERR: 651 }
648 if (!elems.perr || elems.perr_len != 12) 652 if (elems.perr) {
653 if (elems.perr_len != 12)
649 /* Right now we support only one destination per PERR */ 654 /* Right now we support only one destination per PERR */
650 return; 655 return;
651 hwmp_perr_frame_process(sdata, mgmt, elems.perr); 656 hwmp_perr_frame_process(sdata, mgmt, elems.perr);
652 default:
653 return;
654 } 657 }
655 658
656} 659}