aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh_hwmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mesh_hwmp.c')
-rw-r--r--net/mac80211/mesh_hwmp.c61
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
1006mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) 1018mesh_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}