aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c47
-rw-r--r--net/mac80211/mesh.c17
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/tkip.c6
5 files changed, 38 insertions, 36 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8e53ce7ed444..c7314bf4bec2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -354,7 +354,7 @@ struct ieee80211_if_sta {
354 int preq_queue_len; 354 int preq_queue_len;
355 struct mesh_stats mshstats; 355 struct mesh_stats mshstats;
356 struct mesh_config mshcfg; 356 struct mesh_config mshcfg;
357 u8 mesh_seqnum[3]; 357 u32 mesh_seqnum;
358 bool accepting_plinks; 358 bool accepting_plinks;
359#endif 359#endif
360 u16 aid; 360 u16 aid;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index e9a978979d38..9ad4e3631b6b 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -255,22 +255,8 @@ static int ieee80211_open(struct net_device *dev)
255 255
256 switch (sdata->vif.type) { 256 switch (sdata->vif.type) {
257 case IEEE80211_IF_TYPE_WDS: 257 case IEEE80211_IF_TYPE_WDS:
258 if (is_zero_ether_addr(sdata->u.wds.remote_addr)) 258 if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
259 return -ENOLINK; 259 return -ENOLINK;
260
261 /* Create STA entry for the WDS peer */
262 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
263 GFP_KERNEL);
264 if (!sta)
265 return -ENOMEM;
266
267 sta->flags |= WLAN_STA_AUTHORIZED;
268
269 res = sta_info_insert(sta);
270 if (res) {
271 /* STA has been freed */
272 return res;
273 }
274 break; 260 break;
275 case IEEE80211_IF_TYPE_VLAN: 261 case IEEE80211_IF_TYPE_VLAN:
276 if (!sdata->u.vlan.ap) 262 if (!sdata->u.vlan.ap)
@@ -337,10 +323,8 @@ static int ieee80211_open(struct net_device *dev)
337 conf.type = sdata->vif.type; 323 conf.type = sdata->vif.type;
338 conf.mac_addr = dev->dev_addr; 324 conf.mac_addr = dev->dev_addr;
339 res = local->ops->add_interface(local_to_hw(local), &conf); 325 res = local->ops->add_interface(local_to_hw(local), &conf);
340 if (res && !local->open_count && local->ops->stop)
341 local->ops->stop(local_to_hw(local));
342 if (res) 326 if (res)
343 return res; 327 goto err_stop;
344 328
345 ieee80211_if_config(dev); 329 ieee80211_if_config(dev);
346 ieee80211_reset_erp_info(dev); 330 ieee80211_reset_erp_info(dev);
@@ -353,9 +337,29 @@ static int ieee80211_open(struct net_device *dev)
353 netif_carrier_on(dev); 337 netif_carrier_on(dev);
354 } 338 }
355 339
340 if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
341 /* Create STA entry for the WDS peer */
342 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
343 GFP_KERNEL);
344 if (!sta) {
345 res = -ENOMEM;
346 goto err_del_interface;
347 }
348
349 sta->flags |= WLAN_STA_AUTHORIZED;
350
351 res = sta_info_insert(sta);
352 if (res) {
353 /* STA has been freed */
354 goto err_del_interface;
355 }
356 }
357
356 if (local->open_count == 0) { 358 if (local->open_count == 0) {
357 res = dev_open(local->mdev); 359 res = dev_open(local->mdev);
358 WARN_ON(res); 360 WARN_ON(res);
361 if (res)
362 goto err_del_interface;
359 tasklet_enable(&local->tx_pending_tasklet); 363 tasklet_enable(&local->tx_pending_tasklet);
360 tasklet_enable(&local->tasklet); 364 tasklet_enable(&local->tasklet);
361 } 365 }
@@ -390,6 +394,12 @@ static int ieee80211_open(struct net_device *dev)
390 netif_start_queue(dev); 394 netif_start_queue(dev);
391 395
392 return 0; 396 return 0;
397 err_del_interface:
398 local->ops->remove_interface(local_to_hw(local), &conf);
399 err_stop:
400 if (!local->open_count && local->ops->stop)
401 local->ops->stop(local_to_hw(local));
402 return res;
393} 403}
394 404
395static int ieee80211_stop(struct net_device *dev) 405static int ieee80211_stop(struct net_device *dev)
@@ -975,6 +985,7 @@ static int __ieee80211_if_config(struct net_device *dev,
975 conf.ssid_len = sdata->u.sta.ssid_len; 985 conf.ssid_len = sdata->u.sta.ssid_len;
976 } else if (ieee80211_vif_is_mesh(&sdata->vif)) { 986 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
977 conf.beacon = beacon; 987 conf.beacon = beacon;
988 conf.beacon_control = control;
978 ieee80211_start_mesh(dev); 989 ieee80211_start_mesh(dev);
979 } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { 990 } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
980 conf.ssid = sdata->u.ap.ssid; 991 conf.ssid = sdata->u.ap.ssid;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 594a3356a508..f76bc26ae4d2 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -8,6 +8,7 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <asm/unaligned.h>
11#include "ieee80211_i.h" 12#include "ieee80211_i.h"
12#include "mesh.h" 13#include "mesh.h"
13 14
@@ -167,8 +168,8 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
167 struct rmc_entry *p, *n; 168 struct rmc_entry *p, *n;
168 169
169 /* Don't care about endianness since only match matters */ 170 /* Don't care about endianness since only match matters */
170 memcpy(&seqnum, mesh_hdr->seqnum, sizeof(mesh_hdr->seqnum)); 171 memcpy(&seqnum, &mesh_hdr->seqnum, sizeof(mesh_hdr->seqnum));
171 idx = mesh_hdr->seqnum[0] & rmc->idx_mask; 172 idx = le32_to_cpu(mesh_hdr->seqnum) & rmc->idx_mask;
172 list_for_each_entry_safe(p, n, &rmc->bucket[idx].list, list) { 173 list_for_each_entry_safe(p, n, &rmc->bucket[idx].list, list) {
173 ++entries; 174 ++entries;
174 if (time_after(jiffies, p->exp_time) || 175 if (time_after(jiffies, p->exp_time) ||
@@ -393,16 +394,8 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
393{ 394{
394 meshhdr->flags = 0; 395 meshhdr->flags = 0;
395 meshhdr->ttl = sdata->u.sta.mshcfg.dot11MeshTTL; 396 meshhdr->ttl = sdata->u.sta.mshcfg.dot11MeshTTL;
396 397 put_unaligned(cpu_to_le32(sdata->u.sta.mesh_seqnum), &meshhdr->seqnum);
397 meshhdr->seqnum[0] = sdata->u.sta.mesh_seqnum[0]++; 398 sdata->u.sta.mesh_seqnum++;
398 meshhdr->seqnum[1] = sdata->u.sta.mesh_seqnum[1];
399 meshhdr->seqnum[2] = sdata->u.sta.mesh_seqnum[2];
400
401 if (sdata->u.sta.mesh_seqnum[0] == 0) {
402 sdata->u.sta.mesh_seqnum[1]++;
403 if (sdata->u.sta.mesh_seqnum[1] == 0)
404 sdata->u.sta.mesh_seqnum[2]++;
405 }
406 399
407 return 5; 400 return 5;
408} 401}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 9ee3affab346..2e161f6d8288 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -140,7 +140,7 @@ struct rmc_entry {
140 140
141struct mesh_rmc { 141struct mesh_rmc {
142 struct rmc_entry bucket[RMC_BUCKETS]; 142 struct rmc_entry bucket[RMC_BUCKETS];
143 u8 idx_mask; 143 u32 idx_mask;
144}; 144};
145 145
146 146
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index dddbfd60f351..09093da24af6 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -230,10 +230,8 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
230 230
231 iv16 = data[hdr_len] << 8; 231 iv16 = data[hdr_len] << 8;
232 iv16 += data[hdr_len + 2]; 232 iv16 += data[hdr_len + 2];
233 iv32 = data[hdr_len + 4] + 233 iv32 = data[hdr_len + 4] | (data[hdr_len + 5] << 8) |
234 (data[hdr_len + 5] >> 8) + 234 (data[hdr_len + 6] << 16) | (data[hdr_len + 7] << 24);
235 (data[hdr_len + 6] >> 16) +
236 (data[hdr_len + 7] >> 24);
237 235
238#ifdef CONFIG_TKIP_DEBUG 236#ifdef CONFIG_TKIP_DEBUG
239 printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", 237 printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n",