diff options
Diffstat (limited to 'net/mac80211/mesh_hwmp.c')
| -rw-r--r-- | net/mac80211/mesh_hwmp.c | 130 |
1 files changed, 86 insertions, 44 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 3d8e55ae6ab6..fd4f76a3e139 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
| @@ -11,7 +11,8 @@ | |||
| 11 | #include "mesh.h" | 11 | #include "mesh.h" |
| 12 | 12 | ||
| 13 | #ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG | 13 | #ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG |
| 14 | #define mhwmp_dbg(fmt, args...) printk(KERN_DEBUG "Mesh HWMP: " fmt, ##args) | 14 | #define mhwmp_dbg(fmt, args...) \ |
| 15 | printk(KERN_DEBUG "Mesh HWMP (%s): " fmt "\n", sdata->name, ##args) | ||
| 15 | #else | 16 | #else |
| 16 | #define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) | 17 | #define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) |
| 17 | #endif | 18 | #endif |
| @@ -68,12 +69,12 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae) | |||
| 68 | #define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x) | 69 | #define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x) |
| 69 | #define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x) | 70 | #define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x) |
| 70 | #define PREP_IE_TTL(x) PREQ_IE_TTL(x) | 71 | #define PREP_IE_TTL(x) PREQ_IE_TTL(x) |
| 71 | #define PREP_IE_ORIG_ADDR(x) (x + 3) | 72 | #define PREP_IE_ORIG_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21) |
| 72 | #define PREP_IE_ORIG_SN(x) u32_field_get(x, 9, 0) | 73 | #define PREP_IE_ORIG_SN(x) u32_field_get(x, 27, AE_F_SET(x)) |
| 73 | #define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x)) | 74 | #define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x)) |
| 74 | #define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x)) | 75 | #define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x)) |
| 75 | #define PREP_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21) | 76 | #define PREP_IE_TARGET_ADDR(x) (x + 3) |
| 76 | #define PREP_IE_TARGET_SN(x) u32_field_get(x, 27, AE_F_SET(x)) | 77 | #define PREP_IE_TARGET_SN(x) u32_field_get(x, 9, 0) |
| 77 | 78 | ||
| 78 | #define PERR_IE_TTL(x) (*(x)) | 79 | #define PERR_IE_TTL(x) (*(x)) |
| 79 | #define PERR_IE_TARGET_FLAGS(x) (*(x + 2)) | 80 | #define PERR_IE_TARGET_FLAGS(x) (*(x + 2)) |
| @@ -132,24 +133,25 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
| 132 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 133 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
| 133 | /* BSSID == SA */ | 134 | /* BSSID == SA */ |
| 134 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | 135 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
| 135 | mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL; | 136 | mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; |
| 136 | mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; | 137 | mgmt->u.action.u.mesh_action.action_code = |
| 138 | WLAN_MESH_ACTION_HWMP_PATH_SELECTION; | ||
| 137 | 139 | ||
| 138 | switch (action) { | 140 | switch (action) { |
| 139 | case MPATH_PREQ: | 141 | case MPATH_PREQ: |
| 140 | mhwmp_dbg("sending PREQ to %pM\n", target); | 142 | mhwmp_dbg("sending PREQ to %pM", target); |
| 141 | ie_len = 37; | 143 | ie_len = 37; |
| 142 | pos = skb_put(skb, 2 + ie_len); | 144 | pos = skb_put(skb, 2 + ie_len); |
| 143 | *pos++ = WLAN_EID_PREQ; | 145 | *pos++ = WLAN_EID_PREQ; |
| 144 | break; | 146 | break; |
| 145 | case MPATH_PREP: | 147 | case MPATH_PREP: |
| 146 | mhwmp_dbg("sending PREP to %pM\n", target); | 148 | mhwmp_dbg("sending PREP to %pM", target); |
| 147 | ie_len = 31; | 149 | ie_len = 31; |
| 148 | pos = skb_put(skb, 2 + ie_len); | 150 | pos = skb_put(skb, 2 + ie_len); |
| 149 | *pos++ = WLAN_EID_PREP; | 151 | *pos++ = WLAN_EID_PREP; |
| 150 | break; | 152 | break; |
| 151 | case MPATH_RANN: | 153 | case MPATH_RANN: |
| 152 | mhwmp_dbg("sending RANN from %pM\n", orig_addr); | 154 | mhwmp_dbg("sending RANN from %pM", orig_addr); |
| 153 | ie_len = sizeof(struct ieee80211_rann_ie); | 155 | ie_len = sizeof(struct ieee80211_rann_ie); |
| 154 | pos = skb_put(skb, 2 + ie_len); | 156 | pos = skb_put(skb, 2 + ie_len); |
| 155 | *pos++ = WLAN_EID_RANN; | 157 | *pos++ = WLAN_EID_RANN; |
| @@ -163,29 +165,37 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
| 163 | *pos++ = flags; | 165 | *pos++ = flags; |
| 164 | *pos++ = hop_count; | 166 | *pos++ = hop_count; |
| 165 | *pos++ = ttl; | 167 | *pos++ = ttl; |
| 166 | if (action == MPATH_PREQ) { | 168 | if (action == MPATH_PREP) { |
| 167 | memcpy(pos, &preq_id, 4); | 169 | memcpy(pos, target, ETH_ALEN); |
| 170 | pos += ETH_ALEN; | ||
| 171 | memcpy(pos, &target_sn, 4); | ||
| 168 | pos += 4; | 172 | pos += 4; |
| 169 | } | 173 | } else { |
| 170 | memcpy(pos, orig_addr, ETH_ALEN); | 174 | if (action == MPATH_PREQ) { |
| 171 | pos += ETH_ALEN; | 175 | memcpy(pos, &preq_id, 4); |
| 172 | memcpy(pos, &orig_sn, 4); | 176 | pos += 4; |
| 173 | pos += 4; | 177 | } |
| 174 | if (action != MPATH_RANN) { | 178 | memcpy(pos, orig_addr, ETH_ALEN); |
| 175 | memcpy(pos, &lifetime, 4); | 179 | pos += ETH_ALEN; |
| 180 | memcpy(pos, &orig_sn, 4); | ||
| 176 | pos += 4; | 181 | pos += 4; |
| 177 | } | 182 | } |
| 183 | memcpy(pos, &lifetime, 4); /* interval for RANN */ | ||
| 184 | pos += 4; | ||
| 178 | memcpy(pos, &metric, 4); | 185 | memcpy(pos, &metric, 4); |
| 179 | pos += 4; | 186 | pos += 4; |
| 180 | if (action == MPATH_PREQ) { | 187 | if (action == MPATH_PREQ) { |
| 181 | /* destination count */ | 188 | *pos++ = 1; /* destination count */ |
| 182 | *pos++ = 1; | ||
| 183 | *pos++ = target_flags; | 189 | *pos++ = target_flags; |
| 184 | } | ||
| 185 | if (action != MPATH_RANN) { | ||
| 186 | memcpy(pos, target, ETH_ALEN); | 190 | memcpy(pos, target, ETH_ALEN); |
| 187 | pos += ETH_ALEN; | 191 | pos += ETH_ALEN; |
| 188 | memcpy(pos, &target_sn, 4); | 192 | memcpy(pos, &target_sn, 4); |
| 193 | pos += 4; | ||
| 194 | } else if (action == MPATH_PREP) { | ||
| 195 | memcpy(pos, orig_addr, ETH_ALEN); | ||
| 196 | pos += ETH_ALEN; | ||
| 197 | memcpy(pos, &orig_sn, 4); | ||
| 198 | pos += 4; | ||
| 189 | } | 199 | } |
| 190 | 200 | ||
| 191 | ieee80211_tx_skb(sdata, skb); | 201 | ieee80211_tx_skb(sdata, skb); |
| @@ -224,9 +234,11 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, | |||
| 224 | 234 | ||
| 225 | memcpy(mgmt->da, ra, ETH_ALEN); | 235 | memcpy(mgmt->da, ra, ETH_ALEN); |
| 226 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 236 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
| 227 | /* BSSID is left zeroed, wildcard value */ | 237 | /* BSSID == SA */ |
| 228 | mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL; | 238 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
| 229 | mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; | 239 | mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; |
| 240 | mgmt->u.action.u.mesh_action.action_code = | ||
| 241 | WLAN_MESH_ACTION_HWMP_PATH_SELECTION; | ||
| 230 | ie_len = 15; | 242 | ie_len = 15; |
| 231 | pos = skb_put(skb, 2 + ie_len); | 243 | pos = skb_put(skb, 2 + ie_len); |
| 232 | *pos++ = WLAN_EID_PERR; | 244 | *pos++ = WLAN_EID_PERR; |
| @@ -483,10 +495,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
| 483 | orig_sn = PREQ_IE_ORIG_SN(preq_elem); | 495 | orig_sn = PREQ_IE_ORIG_SN(preq_elem); |
| 484 | target_flags = PREQ_IE_TARGET_F(preq_elem); | 496 | target_flags = PREQ_IE_TARGET_F(preq_elem); |
| 485 | 497 | ||
| 486 | mhwmp_dbg("received PREQ from %pM\n", orig_addr); | 498 | mhwmp_dbg("received PREQ from %pM", orig_addr); |
| 487 | 499 | ||
| 488 | if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) { | 500 | if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) { |
| 489 | mhwmp_dbg("PREQ is for us\n"); | 501 | mhwmp_dbg("PREQ is for us"); |
| 490 | forward = false; | 502 | forward = false; |
| 491 | reply = true; | 503 | reply = true; |
| 492 | metric = 0; | 504 | metric = 0; |
| @@ -522,7 +534,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
| 522 | lifetime = PREQ_IE_LIFETIME(preq_elem); | 534 | lifetime = PREQ_IE_LIFETIME(preq_elem); |
| 523 | ttl = ifmsh->mshcfg.element_ttl; | 535 | ttl = ifmsh->mshcfg.element_ttl; |
| 524 | if (ttl != 0) { | 536 | if (ttl != 0) { |
| 525 | mhwmp_dbg("replying to the PREQ\n"); | 537 | mhwmp_dbg("replying to the PREQ"); |
| 526 | mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr, | 538 | mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr, |
| 527 | cpu_to_le32(target_sn), 0, orig_addr, | 539 | cpu_to_le32(target_sn), 0, orig_addr, |
| 528 | cpu_to_le32(orig_sn), mgmt->sa, 0, ttl, | 540 | cpu_to_le32(orig_sn), mgmt->sa, 0, ttl, |
| @@ -542,7 +554,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
| 542 | ifmsh->mshstats.dropped_frames_ttl++; | 554 | ifmsh->mshstats.dropped_frames_ttl++; |
| 543 | return; | 555 | return; |
| 544 | } | 556 | } |
| 545 | mhwmp_dbg("forwarding the PREQ from %pM\n", orig_addr); | 557 | mhwmp_dbg("forwarding the PREQ from %pM", orig_addr); |
| 546 | --ttl; | 558 | --ttl; |
| 547 | flags = PREQ_IE_FLAGS(preq_elem); | 559 | flags = PREQ_IE_FLAGS(preq_elem); |
| 548 | preq_id = PREQ_IE_PREQ_ID(preq_elem); | 560 | preq_id = PREQ_IE_PREQ_ID(preq_elem); |
| @@ -577,7 +589,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, | |||
| 577 | u8 next_hop[ETH_ALEN]; | 589 | u8 next_hop[ETH_ALEN]; |
| 578 | u32 target_sn, orig_sn, lifetime; | 590 | u32 target_sn, orig_sn, lifetime; |
| 579 | 591 | ||
| 580 | mhwmp_dbg("received PREP from %pM\n", PREP_IE_ORIG_ADDR(prep_elem)); | 592 | mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); |
| 581 | 593 | ||
| 582 | /* Note that we divert from the draft nomenclature and denominate | 594 | /* Note that we divert from the draft nomenclature and denominate |
| 583 | * destination to what the draft refers to as origininator. So in this | 595 | * destination to what the draft refers to as origininator. So in this |
| @@ -683,6 +695,8 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
| 683 | u8 ttl, flags, hopcount; | 695 | u8 ttl, flags, hopcount; |
| 684 | u8 *orig_addr; | 696 | u8 *orig_addr; |
| 685 | u32 orig_sn, metric; | 697 | u32 orig_sn, metric; |
| 698 | u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; | ||
| 699 | bool root_is_gate; | ||
| 686 | 700 | ||
| 687 | ttl = rann->rann_ttl; | 701 | ttl = rann->rann_ttl; |
| 688 | if (ttl <= 1) { | 702 | if (ttl <= 1) { |
| @@ -691,12 +705,19 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
| 691 | } | 705 | } |
| 692 | ttl--; | 706 | ttl--; |
| 693 | flags = rann->rann_flags; | 707 | flags = rann->rann_flags; |
| 708 | root_is_gate = !!(flags & RANN_FLAG_IS_GATE); | ||
| 694 | orig_addr = rann->rann_addr; | 709 | orig_addr = rann->rann_addr; |
| 695 | orig_sn = rann->rann_seq; | 710 | orig_sn = rann->rann_seq; |
| 696 | hopcount = rann->rann_hopcount; | 711 | hopcount = rann->rann_hopcount; |
| 697 | hopcount++; | 712 | hopcount++; |
| 698 | metric = rann->rann_metric; | 713 | metric = rann->rann_metric; |
| 699 | mhwmp_dbg("received RANN from %pM\n", orig_addr); | 714 | |
| 715 | /* Ignore our own RANNs */ | ||
| 716 | if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) | ||
| 717 | return; | ||
| 718 | |||
| 719 | mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr, | ||
| 720 | root_is_gate); | ||
| 700 | 721 | ||
| 701 | rcu_read_lock(); | 722 | rcu_read_lock(); |
| 702 | mpath = mesh_path_lookup(orig_addr, sdata); | 723 | mpath = mesh_path_lookup(orig_addr, sdata); |
| @@ -708,18 +729,28 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
| 708 | sdata->u.mesh.mshstats.dropped_frames_no_route++; | 729 | sdata->u.mesh.mshstats.dropped_frames_no_route++; |
| 709 | return; | 730 | return; |
| 710 | } | 731 | } |
| 711 | mesh_queue_preq(mpath, | ||
| 712 | PREQ_Q_F_START | PREQ_Q_F_REFRESH); | ||
| 713 | } | 732 | } |
| 733 | |||
| 734 | if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) || | ||
| 735 | time_after(jiffies, mpath->exp_time - 1*HZ)) && | ||
| 736 | !(mpath->flags & MESH_PATH_FIXED)) { | ||
| 737 | mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name, | ||
| 738 | orig_addr); | ||
| 739 | mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); | ||
| 740 | } | ||
| 741 | |||
| 714 | if (mpath->sn < orig_sn) { | 742 | if (mpath->sn < orig_sn) { |
| 715 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, | 743 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, |
| 716 | cpu_to_le32(orig_sn), | 744 | cpu_to_le32(orig_sn), |
| 717 | 0, NULL, 0, broadcast_addr, | 745 | 0, NULL, 0, broadcast_addr, |
| 718 | hopcount, ttl, 0, | 746 | hopcount, ttl, cpu_to_le32(interval), |
| 719 | cpu_to_le32(metric + mpath->metric), | 747 | cpu_to_le32(metric + mpath->metric), |
| 720 | 0, sdata); | 748 | 0, sdata); |
| 721 | mpath->sn = orig_sn; | 749 | mpath->sn = orig_sn; |
| 722 | } | 750 | } |
| 751 | if (root_is_gate) | ||
| 752 | mesh_path_add_gate(mpath); | ||
| 753 | |||
| 723 | rcu_read_unlock(); | 754 | rcu_read_unlock(); |
| 724 | } | 755 | } |
| 725 | 756 | ||
| @@ -787,7 +818,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
| 787 | 818 | ||
| 788 | preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); | 819 | preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); |
| 789 | if (!preq_node) { | 820 | if (!preq_node) { |
| 790 | mhwmp_dbg("could not allocate PREQ node\n"); | 821 | mhwmp_dbg("could not allocate PREQ node"); |
| 791 | return; | 822 | return; |
| 792 | } | 823 | } |
| 793 | 824 | ||
| @@ -796,7 +827,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
| 796 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); | 827 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); |
| 797 | kfree(preq_node); | 828 | kfree(preq_node); |
| 798 | if (printk_ratelimit()) | 829 | if (printk_ratelimit()) |
| 799 | mhwmp_dbg("PREQ node queue full\n"); | 830 | mhwmp_dbg("PREQ node queue full"); |
| 800 | return; | 831 | return; |
| 801 | } | 832 | } |
| 802 | 833 | ||
| @@ -981,35 +1012,46 @@ void mesh_path_timer(unsigned long data) | |||
| 981 | { | 1012 | { |
| 982 | struct mesh_path *mpath = (void *) data; | 1013 | struct mesh_path *mpath = (void *) data; |
| 983 | struct ieee80211_sub_if_data *sdata = mpath->sdata; | 1014 | struct ieee80211_sub_if_data *sdata = mpath->sdata; |
| 1015 | int ret; | ||
| 984 | 1016 | ||
| 985 | if (sdata->local->quiescing) | 1017 | if (sdata->local->quiescing) |
| 986 | return; | 1018 | return; |
| 987 | 1019 | ||
| 988 | spin_lock_bh(&mpath->state_lock); | 1020 | spin_lock_bh(&mpath->state_lock); |
| 989 | if (mpath->flags & MESH_PATH_RESOLVED || | 1021 | if (mpath->flags & MESH_PATH_RESOLVED || |
| 990 | (!(mpath->flags & MESH_PATH_RESOLVING))) | 1022 | (!(mpath->flags & MESH_PATH_RESOLVING))) { |
| 991 | mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED); | 1023 | mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED); |
| 992 | else if (mpath->discovery_retries < max_preq_retries(sdata)) { | 1024 | spin_unlock_bh(&mpath->state_lock); |
| 1025 | } else if (mpath->discovery_retries < max_preq_retries(sdata)) { | ||
| 993 | ++mpath->discovery_retries; | 1026 | ++mpath->discovery_retries; |
| 994 | mpath->discovery_timeout *= 2; | 1027 | mpath->discovery_timeout *= 2; |
| 1028 | spin_unlock_bh(&mpath->state_lock); | ||
| 995 | mesh_queue_preq(mpath, 0); | 1029 | mesh_queue_preq(mpath, 0); |
| 996 | } else { | 1030 | } else { |
| 997 | mpath->flags = 0; | 1031 | mpath->flags = 0; |
| 998 | mpath->exp_time = jiffies; | 1032 | mpath->exp_time = jiffies; |
| 999 | mesh_path_flush_pending(mpath); | 1033 | spin_unlock_bh(&mpath->state_lock); |
| 1034 | if (!mpath->is_gate && mesh_gate_num(sdata) > 0) { | ||
| 1035 | ret = mesh_path_send_to_gates(mpath); | ||
| 1036 | if (ret) | ||
| 1037 | mhwmp_dbg("no gate was reachable"); | ||
| 1038 | } else | ||
| 1039 | mesh_path_flush_pending(mpath); | ||
| 1000 | } | 1040 | } |
| 1001 | |||
| 1002 | spin_unlock_bh(&mpath->state_lock); | ||
| 1003 | } | 1041 | } |
| 1004 | 1042 | ||
| 1005 | void | 1043 | void |
| 1006 | mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) | 1044 | mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) |
| 1007 | { | 1045 | { |
| 1008 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 1046 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
| 1047 | u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; | ||
| 1048 | u8 flags; | ||
| 1009 | 1049 | ||
| 1010 | mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->vif.addr, | 1050 | flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol) |
| 1051 | ? RANN_FLAG_IS_GATE : 0; | ||
| 1052 | mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, | ||
| 1011 | cpu_to_le32(++ifmsh->sn), | 1053 | cpu_to_le32(++ifmsh->sn), |
| 1012 | 0, NULL, 0, broadcast_addr, | 1054 | 0, NULL, 0, broadcast_addr, |
| 1013 | 0, sdata->u.mesh.mshcfg.element_ttl, | 1055 | 0, sdata->u.mesh.mshcfg.element_ttl, |
| 1014 | 0, 0, 0, sdata); | 1056 | cpu_to_le32(interval), 0, 0, sdata); |
| 1015 | } | 1057 | } |
