diff options
Diffstat (limited to 'net/mac80211/mesh_hwmp.c')
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 61 |
1 files changed, 37 insertions, 24 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 3d8e55ae6ab6..9c3c0b86a740 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -68,12 +68,12 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae) | |||
68 | #define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x) | 68 | #define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x) |
69 | #define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x) | 69 | #define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x) |
70 | #define PREP_IE_TTL(x) PREQ_IE_TTL(x) | 70 | #define PREP_IE_TTL(x) PREQ_IE_TTL(x) |
71 | #define PREP_IE_ORIG_ADDR(x) (x + 3) | 71 | #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) | 72 | #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)) | 73 | #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)) | 74 | #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) | 75 | #define PREP_IE_TARGET_ADDR(x) (x + 3) |
76 | #define PREP_IE_TARGET_SN(x) u32_field_get(x, 27, AE_F_SET(x)) | 76 | #define PREP_IE_TARGET_SN(x) u32_field_get(x, 9, 0) |
77 | 77 | ||
78 | #define PERR_IE_TTL(x) (*(x)) | 78 | #define PERR_IE_TTL(x) (*(x)) |
79 | #define PERR_IE_TARGET_FLAGS(x) (*(x + 2)) | 79 | #define PERR_IE_TARGET_FLAGS(x) (*(x + 2)) |
@@ -132,8 +132,9 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
132 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 132 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
133 | /* BSSID == SA */ | 133 | /* BSSID == SA */ |
134 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | 134 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
135 | mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL; | 135 | mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; |
136 | mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; | 136 | mgmt->u.action.u.mesh_action.action_code = |
137 | WLAN_MESH_ACTION_HWMP_PATH_SELECTION; | ||
137 | 138 | ||
138 | switch (action) { | 139 | switch (action) { |
139 | case MPATH_PREQ: | 140 | case MPATH_PREQ: |
@@ -163,29 +164,37 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
163 | *pos++ = flags; | 164 | *pos++ = flags; |
164 | *pos++ = hop_count; | 165 | *pos++ = hop_count; |
165 | *pos++ = ttl; | 166 | *pos++ = ttl; |
166 | if (action == MPATH_PREQ) { | 167 | if (action == MPATH_PREP) { |
167 | memcpy(pos, &preq_id, 4); | 168 | memcpy(pos, target, ETH_ALEN); |
169 | pos += ETH_ALEN; | ||
170 | memcpy(pos, &target_sn, 4); | ||
168 | pos += 4; | 171 | pos += 4; |
169 | } | 172 | } else { |
170 | memcpy(pos, orig_addr, ETH_ALEN); | 173 | if (action == MPATH_PREQ) { |
171 | pos += ETH_ALEN; | 174 | memcpy(pos, &preq_id, 4); |
172 | memcpy(pos, &orig_sn, 4); | 175 | pos += 4; |
173 | pos += 4; | 176 | } |
174 | if (action != MPATH_RANN) { | 177 | memcpy(pos, orig_addr, ETH_ALEN); |
175 | memcpy(pos, &lifetime, 4); | 178 | pos += ETH_ALEN; |
179 | memcpy(pos, &orig_sn, 4); | ||
176 | pos += 4; | 180 | pos += 4; |
177 | } | 181 | } |
182 | memcpy(pos, &lifetime, 4); /* interval for RANN */ | ||
183 | pos += 4; | ||
178 | memcpy(pos, &metric, 4); | 184 | memcpy(pos, &metric, 4); |
179 | pos += 4; | 185 | pos += 4; |
180 | if (action == MPATH_PREQ) { | 186 | if (action == MPATH_PREQ) { |
181 | /* destination count */ | 187 | *pos++ = 1; /* destination count */ |
182 | *pos++ = 1; | ||
183 | *pos++ = target_flags; | 188 | *pos++ = target_flags; |
184 | } | ||
185 | if (action != MPATH_RANN) { | ||
186 | memcpy(pos, target, ETH_ALEN); | 189 | memcpy(pos, target, ETH_ALEN); |
187 | pos += ETH_ALEN; | 190 | pos += ETH_ALEN; |
188 | memcpy(pos, &target_sn, 4); | 191 | memcpy(pos, &target_sn, 4); |
192 | pos += 4; | ||
193 | } else if (action == MPATH_PREP) { | ||
194 | memcpy(pos, orig_addr, ETH_ALEN); | ||
195 | pos += ETH_ALEN; | ||
196 | memcpy(pos, &orig_sn, 4); | ||
197 | pos += 4; | ||
189 | } | 198 | } |
190 | 199 | ||
191 | ieee80211_tx_skb(sdata, skb); | 200 | ieee80211_tx_skb(sdata, skb); |
@@ -224,9 +233,11 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, | |||
224 | 233 | ||
225 | memcpy(mgmt->da, ra, ETH_ALEN); | 234 | memcpy(mgmt->da, ra, ETH_ALEN); |
226 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 235 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
227 | /* BSSID is left zeroed, wildcard value */ | 236 | /* BSSID == SA */ |
228 | mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL; | 237 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
229 | mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; | 238 | mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; |
239 | mgmt->u.action.u.mesh_action.action_code = | ||
240 | WLAN_MESH_ACTION_HWMP_PATH_SELECTION; | ||
230 | ie_len = 15; | 241 | ie_len = 15; |
231 | pos = skb_put(skb, 2 + ie_len); | 242 | pos = skb_put(skb, 2 + ie_len); |
232 | *pos++ = WLAN_EID_PERR; | 243 | *pos++ = WLAN_EID_PERR; |
@@ -683,6 +694,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
683 | u8 ttl, flags, hopcount; | 694 | u8 ttl, flags, hopcount; |
684 | u8 *orig_addr; | 695 | u8 *orig_addr; |
685 | u32 orig_sn, metric; | 696 | u32 orig_sn, metric; |
697 | u32 interval = cpu_to_le32(IEEE80211_MESH_RANN_INTERVAL); | ||
686 | 698 | ||
687 | ttl = rann->rann_ttl; | 699 | ttl = rann->rann_ttl; |
688 | if (ttl <= 1) { | 700 | if (ttl <= 1) { |
@@ -715,7 +727,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
715 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, | 727 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, |
716 | cpu_to_le32(orig_sn), | 728 | cpu_to_le32(orig_sn), |
717 | 0, NULL, 0, broadcast_addr, | 729 | 0, NULL, 0, broadcast_addr, |
718 | hopcount, ttl, 0, | 730 | hopcount, ttl, interval, |
719 | cpu_to_le32(metric + mpath->metric), | 731 | cpu_to_le32(metric + mpath->metric), |
720 | 0, sdata); | 732 | 0, sdata); |
721 | mpath->sn = orig_sn; | 733 | mpath->sn = orig_sn; |
@@ -1006,10 +1018,11 @@ void | |||
1006 | mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) | 1018 | mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) |
1007 | { | 1019 | { |
1008 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 1020 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
1021 | u32 interval = cpu_to_le32(IEEE80211_MESH_RANN_INTERVAL); | ||
1009 | 1022 | ||
1010 | mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->vif.addr, | 1023 | mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->vif.addr, |
1011 | cpu_to_le32(++ifmsh->sn), | 1024 | cpu_to_le32(++ifmsh->sn), |
1012 | 0, NULL, 0, broadcast_addr, | 1025 | 0, NULL, 0, broadcast_addr, |
1013 | 0, sdata->u.mesh.mshcfg.element_ttl, | 1026 | 0, sdata->u.mesh.mshcfg.element_ttl, |
1014 | 0, 0, 0, sdata); | 1027 | interval, 0, 0, sdata); |
1015 | } | 1028 | } |