diff options
author | Rui Paulo <rpaulo@gmail.com> | 2009-11-09 18:46:46 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-11 15:23:58 -0500 |
commit | dbb81c428bf534fcfe94102acca50f6d56504999 (patch) | |
tree | 9dcf3ddc9355eafe24293b4bd68db6560b37223a /net/mac80211 | |
parent | 27db2e423fdeae8815087677261ab72cca7b3c28 (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.c | 47 |
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 | */ |
278 | static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, | 278 | static 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 | } |