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.c91
1 files changed, 39 insertions, 52 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 486819cd02cd..f9514685d45a 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -102,12 +102,11 @@ enum mpath_frame_type {
102static const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 102static const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
103 103
104static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, 104static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
105 const u8 *orig_addr, __le32 orig_sn, 105 const u8 *orig_addr, u32 orig_sn,
106 u8 target_flags, const u8 *target, 106 u8 target_flags, const u8 *target,
107 __le32 target_sn, const u8 *da, 107 u32 target_sn, const u8 *da,
108 u8 hop_count, u8 ttl, 108 u8 hop_count, u8 ttl,
109 __le32 lifetime, __le32 metric, 109 u32 lifetime, u32 metric, u32 preq_id,
110 __le32 preq_id,
111 struct ieee80211_sub_if_data *sdata) 110 struct ieee80211_sub_if_data *sdata)
112{ 111{
113 struct ieee80211_local *local = sdata->local; 112 struct ieee80211_local *local = sdata->local;
@@ -167,33 +166,33 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
167 if (action == MPATH_PREP) { 166 if (action == MPATH_PREP) {
168 memcpy(pos, target, ETH_ALEN); 167 memcpy(pos, target, ETH_ALEN);
169 pos += ETH_ALEN; 168 pos += ETH_ALEN;
170 memcpy(pos, &target_sn, 4); 169 put_unaligned_le32(target_sn, pos);
171 pos += 4; 170 pos += 4;
172 } else { 171 } else {
173 if (action == MPATH_PREQ) { 172 if (action == MPATH_PREQ) {
174 memcpy(pos, &preq_id, 4); 173 put_unaligned_le32(preq_id, pos);
175 pos += 4; 174 pos += 4;
176 } 175 }
177 memcpy(pos, orig_addr, ETH_ALEN); 176 memcpy(pos, orig_addr, ETH_ALEN);
178 pos += ETH_ALEN; 177 pos += ETH_ALEN;
179 memcpy(pos, &orig_sn, 4); 178 put_unaligned_le32(orig_sn, pos);
180 pos += 4; 179 pos += 4;
181 } 180 }
182 memcpy(pos, &lifetime, 4); /* interval for RANN */ 181 put_unaligned_le32(lifetime, pos); /* interval for RANN */
183 pos += 4; 182 pos += 4;
184 memcpy(pos, &metric, 4); 183 put_unaligned_le32(metric, pos);
185 pos += 4; 184 pos += 4;
186 if (action == MPATH_PREQ) { 185 if (action == MPATH_PREQ) {
187 *pos++ = 1; /* destination count */ 186 *pos++ = 1; /* destination count */
188 *pos++ = target_flags; 187 *pos++ = target_flags;
189 memcpy(pos, target, ETH_ALEN); 188 memcpy(pos, target, ETH_ALEN);
190 pos += ETH_ALEN; 189 pos += ETH_ALEN;
191 memcpy(pos, &target_sn, 4); 190 put_unaligned_le32(target_sn, pos);
192 pos += 4; 191 pos += 4;
193 } else if (action == MPATH_PREP) { 192 } else if (action == MPATH_PREP) {
194 memcpy(pos, orig_addr, ETH_ALEN); 193 memcpy(pos, orig_addr, ETH_ALEN);
195 pos += ETH_ALEN; 194 pos += ETH_ALEN;
196 memcpy(pos, &orig_sn, 4); 195 put_unaligned_le32(orig_sn, pos);
197 pos += 4; 196 pos += 4;
198 } 197 }
199 198
@@ -239,8 +238,8 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
239 * frame directly but add it to the pending queue instead. 238 * frame directly but add it to the pending queue instead.
240 */ 239 */
241int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, 240int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
242 u8 ttl, const u8 *target, __le32 target_sn, 241 u8 ttl, const u8 *target, u32 target_sn,
243 __le16 target_rcode, const u8 *ra) 242 u16 target_rcode, const u8 *ra)
244{ 243{
245 struct ieee80211_local *local = sdata->local; 244 struct ieee80211_local *local = sdata->local;
246 struct sk_buff *skb; 245 struct sk_buff *skb;
@@ -254,13 +253,13 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
254 return -EAGAIN; 253 return -EAGAIN;
255 254
256 skb = dev_alloc_skb(local->tx_headroom + 255 skb = dev_alloc_skb(local->tx_headroom +
257 IEEE80211_ENCRYPT_HEADROOM + 256 sdata->encrypt_headroom +
258 IEEE80211_ENCRYPT_TAILROOM + 257 IEEE80211_ENCRYPT_TAILROOM +
259 hdr_len + 258 hdr_len +
260 2 + 15 /* PERR IE */); 259 2 + 15 /* PERR IE */);
261 if (!skb) 260 if (!skb)
262 return -1; 261 return -1;
263 skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM); 262 skb_reserve(skb, local->tx_headroom + sdata->encrypt_headroom);
264 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); 263 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
265 memset(mgmt, 0, hdr_len); 264 memset(mgmt, 0, hdr_len);
266 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 265 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
@@ -293,9 +292,9 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
293 pos++; 292 pos++;
294 memcpy(pos, target, ETH_ALEN); 293 memcpy(pos, target, ETH_ALEN);
295 pos += ETH_ALEN; 294 pos += ETH_ALEN;
296 memcpy(pos, &target_sn, 4); 295 put_unaligned_le32(target_sn, pos);
297 pos += 4; 296 pos += 4;
298 memcpy(pos, &target_rcode, 2); 297 put_unaligned_le16(target_rcode, pos);
299 298
300 /* see note in function header */ 299 /* see note in function header */
301 prepare_frame_for_deferred_tx(sdata, skb); 300 prepare_frame_for_deferred_tx(sdata, skb);
@@ -592,10 +591,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
592 if (ttl != 0) { 591 if (ttl != 0) {
593 mhwmp_dbg(sdata, "replying to the PREQ\n"); 592 mhwmp_dbg(sdata, "replying to the PREQ\n");
594 mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr, 593 mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
595 cpu_to_le32(orig_sn), 0, target_addr, 594 orig_sn, 0, target_addr,
596 cpu_to_le32(target_sn), mgmt->sa, 0, ttl, 595 target_sn, mgmt->sa, 0, ttl,
597 cpu_to_le32(lifetime), cpu_to_le32(metric), 596 lifetime, metric, 0, sdata);
598 0, sdata);
599 } else { 597 } else {
600 ifmsh->mshstats.dropped_frames_ttl++; 598 ifmsh->mshstats.dropped_frames_ttl++;
601 } 599 }
@@ -625,11 +623,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
625 } 623 }
626 624
627 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, 625 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
628 cpu_to_le32(orig_sn), target_flags, target_addr, 626 orig_sn, target_flags, target_addr,
629 cpu_to_le32(target_sn), da, 627 target_sn, da, hopcount, ttl, lifetime,
630 hopcount, ttl, cpu_to_le32(lifetime), 628 metric, preq_id, sdata);
631 cpu_to_le32(metric), cpu_to_le32(preq_id),
632 sdata);
633 if (!is_multicast_ether_addr(da)) 629 if (!is_multicast_ether_addr(da))
634 ifmsh->mshstats.fwded_unicast++; 630 ifmsh->mshstats.fwded_unicast++;
635 else 631 else
@@ -695,11 +691,9 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
695 target_sn = PREP_IE_TARGET_SN(prep_elem); 691 target_sn = PREP_IE_TARGET_SN(prep_elem);
696 orig_sn = PREP_IE_ORIG_SN(prep_elem); 692 orig_sn = PREP_IE_ORIG_SN(prep_elem);
697 693
698 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, 694 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, orig_sn, 0,
699 cpu_to_le32(orig_sn), 0, target_addr, 695 target_addr, target_sn, next_hop, hopcount,
700 cpu_to_le32(target_sn), next_hop, hopcount, 696 ttl, lifetime, metric, 0, sdata);
701 ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
702 0, sdata);
703 rcu_read_unlock(); 697 rcu_read_unlock();
704 698
705 sdata->u.mesh.mshstats.fwded_unicast++; 699 sdata->u.mesh.mshstats.fwded_unicast++;
@@ -750,8 +744,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
750 if (!ifmsh->mshcfg.dot11MeshForwarding) 744 if (!ifmsh->mshcfg.dot11MeshForwarding)
751 goto endperr; 745 goto endperr;
752 mesh_path_error_tx(sdata, ttl, target_addr, 746 mesh_path_error_tx(sdata, ttl, target_addr,
753 cpu_to_le32(target_sn), 747 target_sn, target_rcode,
754 cpu_to_le16(target_rcode),
755 broadcast_addr); 748 broadcast_addr);
756 } else 749 } else
757 spin_unlock_bh(&mpath->state_lock); 750 spin_unlock_bh(&mpath->state_lock);
@@ -847,11 +840,9 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
847 840
848 if (ifmsh->mshcfg.dot11MeshForwarding) { 841 if (ifmsh->mshcfg.dot11MeshForwarding) {
849 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, 842 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
850 cpu_to_le32(orig_sn), 843 orig_sn, 0, NULL, 0, broadcast_addr,
851 0, NULL, 0, broadcast_addr, 844 hopcount, ttl, interval,
852 hopcount, ttl, cpu_to_le32(interval), 845 metric + metric_txsta, 0, sdata);
853 cpu_to_le32(metric + metric_txsta),
854 0, sdata);
855 } 846 }
856 847
857 rcu_read_unlock(); 848 rcu_read_unlock();
@@ -1049,11 +1040,9 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
1049 1040
1050 spin_unlock_bh(&mpath->state_lock); 1041 spin_unlock_bh(&mpath->state_lock);
1051 da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr; 1042 da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr;
1052 mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, 1043 mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, ifmsh->sn,
1053 cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, 1044 target_flags, mpath->dst, mpath->sn, da, 0,
1054 cpu_to_le32(mpath->sn), da, 0, 1045 ttl, lifetime, 0, ifmsh->preq_id++, sdata);
1055 ttl, cpu_to_le32(lifetime), 0,
1056 cpu_to_le32(ifmsh->preq_id++), sdata);
1057 mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); 1046 mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
1058 1047
1059enddiscovery: 1048enddiscovery:
@@ -1212,10 +1201,9 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1212 switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) { 1201 switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) {
1213 case IEEE80211_PROACTIVE_RANN: 1202 case IEEE80211_PROACTIVE_RANN:
1214 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, 1203 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
1215 cpu_to_le32(++ifmsh->sn), 1204 ++ifmsh->sn, 0, NULL, 0, broadcast_addr,
1216 0, NULL, 0, broadcast_addr, 1205 0, ifmsh->mshcfg.element_ttl,
1217 0, ifmsh->mshcfg.element_ttl, 1206 interval, 0, 0, sdata);
1218 cpu_to_le32(interval), 0, 0, sdata);
1219 break; 1207 break;
1220 case IEEE80211_PROACTIVE_PREQ_WITH_PREP: 1208 case IEEE80211_PROACTIVE_PREQ_WITH_PREP:
1221 flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG; 1209 flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG;
@@ -1224,11 +1212,10 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1224 target_flags |= IEEE80211_PREQ_TO_FLAG | 1212 target_flags |= IEEE80211_PREQ_TO_FLAG |
1225 IEEE80211_PREQ_USN_FLAG; 1213 IEEE80211_PREQ_USN_FLAG;
1226 mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr, 1214 mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr,
1227 cpu_to_le32(++ifmsh->sn), target_flags, 1215 ++ifmsh->sn, target_flags,
1228 (u8 *) broadcast_addr, 0, broadcast_addr, 1216 (u8 *) broadcast_addr, 0, broadcast_addr,
1229 0, ifmsh->mshcfg.element_ttl, 1217 0, ifmsh->mshcfg.element_ttl, interval,
1230 cpu_to_le32(interval), 1218 0, ifmsh->preq_id++, sdata);
1231 0, cpu_to_le32(ifmsh->preq_id++), sdata);
1232 break; 1219 break;
1233 default: 1220 default:
1234 mhwmp_dbg(sdata, "Proactive mechanism not supported\n"); 1221 mhwmp_dbg(sdata, "Proactive mechanism not supported\n");