diff options
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r-- | net/mac80211/ibss.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 53c7077ffd4f..421eaa6b0c2b 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) | 31 | #define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) |
32 | 32 | ||
33 | #define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) | 33 | #define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) |
34 | #define IEEE80211_IBSS_MERGE_DELAY 0x400000 | ||
35 | #define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ) | 34 | #define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ) |
36 | 35 | ||
37 | #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 | 36 | #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 |
@@ -41,7 +40,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
41 | struct ieee80211_mgmt *mgmt, | 40 | struct ieee80211_mgmt *mgmt, |
42 | size_t len) | 41 | size_t len) |
43 | { | 42 | { |
44 | u16 auth_alg, auth_transaction, status_code; | 43 | u16 auth_alg, auth_transaction; |
45 | 44 | ||
46 | lockdep_assert_held(&sdata->u.ibss.mtx); | 45 | lockdep_assert_held(&sdata->u.ibss.mtx); |
47 | 46 | ||
@@ -50,7 +49,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
50 | 49 | ||
51 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 50 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
52 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | 51 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); |
53 | status_code = le16_to_cpu(mgmt->u.auth.status_code); | ||
54 | 52 | ||
55 | /* | 53 | /* |
56 | * IEEE 802.11 standard does not require authentication in IBSS | 54 | * IEEE 802.11 standard does not require authentication in IBSS |
@@ -270,7 +268,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
270 | enum ieee80211_band band = rx_status->band; | 268 | enum ieee80211_band band = rx_status->band; |
271 | 269 | ||
272 | if (elems->ds_params && elems->ds_params_len == 1) | 270 | if (elems->ds_params && elems->ds_params_len == 1) |
273 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); | 271 | freq = ieee80211_channel_to_frequency(elems->ds_params[0], |
272 | band); | ||
274 | else | 273 | else |
275 | freq = rx_status->freq; | 274 | freq = rx_status->freq; |
276 | 275 | ||
@@ -354,7 +353,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
354 | if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) | 353 | if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) |
355 | goto put_bss; | 354 | goto put_bss; |
356 | 355 | ||
357 | if (rx_status->flag & RX_FLAG_TSFT) { | 356 | if (rx_status->flag & RX_FLAG_MACTIME_MPDU) { |
358 | /* | 357 | /* |
359 | * For correct IBSS merging we need mactime; since mactime is | 358 | * For correct IBSS merging we need mactime; since mactime is |
360 | * defined as the time the first data symbol of the frame hits | 359 | * defined as the time the first data symbol of the frame hits |
@@ -396,10 +395,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
396 | jiffies); | 395 | jiffies); |
397 | #endif | 396 | #endif |
398 | 397 | ||
399 | /* give slow hardware some time to do the TSF sync */ | ||
400 | if (rx_timestamp < IEEE80211_IBSS_MERGE_DELAY) | ||
401 | goto put_bss; | ||
402 | |||
403 | if (beacon_timestamp > rx_timestamp) { | 398 | if (beacon_timestamp > rx_timestamp) { |
404 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 399 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
405 | printk(KERN_DEBUG "%s: beacon TSF higher than " | 400 | printk(KERN_DEBUG "%s: beacon TSF higher than " |
@@ -531,8 +526,6 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
531 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | 526 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) |
532 | { | 527 | { |
533 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 528 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
534 | struct ieee80211_local *local = sdata->local; | ||
535 | struct ieee80211_supported_band *sband; | ||
536 | u8 bssid[ETH_ALEN]; | 529 | u8 bssid[ETH_ALEN]; |
537 | u16 capability; | 530 | u16 capability; |
538 | int i; | 531 | int i; |
@@ -555,8 +548,6 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
555 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", | 548 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", |
556 | sdata->name, bssid); | 549 | sdata->name, bssid); |
557 | 550 | ||
558 | sband = local->hw.wiphy->bands[ifibss->channel->band]; | ||
559 | |||
560 | capability = WLAN_CAPABILITY_IBSS; | 551 | capability = WLAN_CAPABILITY_IBSS; |
561 | 552 | ||
562 | if (ifibss->privacy) | 553 | if (ifibss->privacy) |
@@ -663,20 +654,24 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
663 | } | 654 | } |
664 | 655 | ||
665 | static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | 656 | static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, |
666 | struct ieee80211_mgmt *mgmt, | 657 | struct sk_buff *req) |
667 | size_t len) | ||
668 | { | 658 | { |
659 | struct ieee80211_mgmt *mgmt = (void *)req->data; | ||
669 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 660 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
670 | struct ieee80211_local *local = sdata->local; | 661 | struct ieee80211_local *local = sdata->local; |
671 | int tx_last_beacon; | 662 | int tx_last_beacon, len = req->len; |
672 | struct sk_buff *skb; | 663 | struct sk_buff *skb; |
673 | struct ieee80211_mgmt *resp; | 664 | struct ieee80211_mgmt *resp; |
665 | struct sk_buff *presp; | ||
674 | u8 *pos, *end; | 666 | u8 *pos, *end; |
675 | 667 | ||
676 | lockdep_assert_held(&ifibss->mtx); | 668 | lockdep_assert_held(&ifibss->mtx); |
677 | 669 | ||
670 | presp = rcu_dereference_protected(ifibss->presp, | ||
671 | lockdep_is_held(&ifibss->mtx)); | ||
672 | |||
678 | if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || | 673 | if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || |
679 | len < 24 + 2 || !ifibss->presp) | 674 | len < 24 + 2 || !presp) |
680 | return; | 675 | return; |
681 | 676 | ||
682 | tx_last_beacon = drv_tx_last_beacon(local); | 677 | tx_last_beacon = drv_tx_last_beacon(local); |
@@ -688,7 +683,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
688 | mgmt->bssid, tx_last_beacon); | 683 | mgmt->bssid, tx_last_beacon); |
689 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 684 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
690 | 685 | ||
691 | if (!tx_last_beacon) | 686 | if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) |
692 | return; | 687 | return; |
693 | 688 | ||
694 | if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && | 689 | if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && |
@@ -714,7 +709,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
714 | } | 709 | } |
715 | 710 | ||
716 | /* Reply with ProbeResp */ | 711 | /* Reply with ProbeResp */ |
717 | skb = skb_copy(ifibss->presp, GFP_KERNEL); | 712 | skb = skb_copy(presp, GFP_KERNEL); |
718 | if (!skb) | 713 | if (!skb) |
719 | return; | 714 | return; |
720 | 715 | ||
@@ -785,7 +780,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
785 | 780 | ||
786 | switch (fc & IEEE80211_FCTL_STYPE) { | 781 | switch (fc & IEEE80211_FCTL_STYPE) { |
787 | case IEEE80211_STYPE_PROBE_REQ: | 782 | case IEEE80211_STYPE_PROBE_REQ: |
788 | ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); | 783 | ieee80211_rx_mgmt_probe_req(sdata, skb); |
789 | break; | 784 | break; |
790 | case IEEE80211_STYPE_PROBE_RESP: | 785 | case IEEE80211_STYPE_PROBE_RESP: |
791 | ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, | 786 | ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, |
@@ -994,7 +989,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
994 | 989 | ||
995 | /* remove beacon */ | 990 | /* remove beacon */ |
996 | kfree(sdata->u.ibss.ie); | 991 | kfree(sdata->u.ibss.ie); |
997 | skb = sdata->u.ibss.presp; | 992 | skb = rcu_dereference_protected(sdata->u.ibss.presp, |
993 | lockdep_is_held(&sdata->u.ibss.mtx)); | ||
998 | rcu_assign_pointer(sdata->u.ibss.presp, NULL); | 994 | rcu_assign_pointer(sdata->u.ibss.presp, NULL); |
999 | sdata->vif.bss_conf.ibss_joined = false; | 995 | sdata->vif.bss_conf.ibss_joined = false; |
1000 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | 996 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | |