diff options
-rw-r--r-- | net/mac80211/mlme.c | 188 |
1 files changed, 97 insertions, 91 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index cffef44cec05..1e4054b273dd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2646,11 +2646,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2646 | struct ieee80211_mgmt *mgmt, | 2646 | struct ieee80211_mgmt *mgmt, |
2647 | size_t len, | 2647 | size_t len, |
2648 | struct ieee80211_rx_status *rx_status, | 2648 | struct ieee80211_rx_status *rx_status, |
2649 | struct ieee802_11_elems *elems, | ||
2649 | int beacon) | 2650 | int beacon) |
2650 | { | 2651 | { |
2651 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2652 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2652 | struct ieee802_11_elems elems; | ||
2653 | size_t baselen; | ||
2654 | int freq, clen; | 2653 | int freq, clen; |
2655 | struct ieee80211_sta_bss *bss; | 2654 | struct ieee80211_sta_bss *bss; |
2656 | struct sta_info *sta; | 2655 | struct sta_info *sta; |
@@ -2669,29 +2668,24 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2669 | print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da)); | 2668 | print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da)); |
2670 | #endif | 2669 | #endif |
2671 | 2670 | ||
2672 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
2673 | if (baselen > len) | ||
2674 | return; | ||
2675 | |||
2676 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); | 2671 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); |
2677 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
2678 | 2672 | ||
2679 | if (ieee80211_vif_is_mesh(&sdata->vif) && elems.mesh_id && | 2673 | if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id && |
2680 | elems.mesh_config && mesh_matches_local(&elems, dev)) { | 2674 | elems->mesh_config && mesh_matches_local(elems, dev)) { |
2681 | u64 rates = ieee80211_sta_get_rates(local, &elems, | 2675 | u64 rates = ieee80211_sta_get_rates(local, elems, |
2682 | rx_status->band); | 2676 | rx_status->band); |
2683 | 2677 | ||
2684 | mesh_neighbour_update(mgmt->sa, rates, dev, | 2678 | mesh_neighbour_update(mgmt->sa, rates, dev, |
2685 | mesh_peer_accepts_plinks(&elems, dev)); | 2679 | mesh_peer_accepts_plinks(elems, dev)); |
2686 | } | 2680 | } |
2687 | 2681 | ||
2688 | rcu_read_lock(); | 2682 | rcu_read_lock(); |
2689 | 2683 | ||
2690 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && | 2684 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates && |
2691 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && | 2685 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && |
2692 | (sta = sta_info_get(local, mgmt->sa))) { | 2686 | (sta = sta_info_get(local, mgmt->sa))) { |
2693 | u64 prev_rates; | 2687 | u64 prev_rates; |
2694 | u64 supp_rates = ieee80211_sta_get_rates(local, &elems, | 2688 | u64 supp_rates = ieee80211_sta_get_rates(local, elems, |
2695 | rx_status->band); | 2689 | rx_status->band); |
2696 | 2690 | ||
2697 | prev_rates = sta->supp_rates[rx_status->band]; | 2691 | prev_rates = sta->supp_rates[rx_status->band]; |
@@ -2716,8 +2710,8 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2716 | 2710 | ||
2717 | rcu_read_unlock(); | 2711 | rcu_read_unlock(); |
2718 | 2712 | ||
2719 | if (elems.ds_params && elems.ds_params_len == 1) | 2713 | if (elems->ds_params && elems->ds_params_len == 1) |
2720 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); | 2714 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); |
2721 | else | 2715 | else |
2722 | freq = rx_status->freq; | 2716 | freq = rx_status->freq; |
2723 | 2717 | ||
@@ -2727,23 +2721,23 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2727 | return; | 2721 | return; |
2728 | 2722 | ||
2729 | #ifdef CONFIG_MAC80211_MESH | 2723 | #ifdef CONFIG_MAC80211_MESH |
2730 | if (elems.mesh_config) | 2724 | if (elems->mesh_config) |
2731 | bss = ieee80211_rx_mesh_bss_get(dev, elems.mesh_id, | 2725 | bss = ieee80211_rx_mesh_bss_get(dev, elems->mesh_id, |
2732 | elems.mesh_id_len, elems.mesh_config, freq); | 2726 | elems->mesh_id_len, elems->mesh_config, freq); |
2733 | else | 2727 | else |
2734 | #endif | 2728 | #endif |
2735 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, | 2729 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, |
2736 | elems.ssid, elems.ssid_len); | 2730 | elems->ssid, elems->ssid_len); |
2737 | if (!bss) { | 2731 | if (!bss) { |
2738 | #ifdef CONFIG_MAC80211_MESH | 2732 | #ifdef CONFIG_MAC80211_MESH |
2739 | if (elems.mesh_config) | 2733 | if (elems->mesh_config) |
2740 | bss = ieee80211_rx_mesh_bss_add(dev, elems.mesh_id, | 2734 | bss = ieee80211_rx_mesh_bss_add(dev, elems->mesh_id, |
2741 | elems.mesh_id_len, elems.mesh_config, | 2735 | elems->mesh_id_len, elems->mesh_config, |
2742 | elems.mesh_config_len, freq); | 2736 | elems->mesh_config_len, freq); |
2743 | else | 2737 | else |
2744 | #endif | 2738 | #endif |
2745 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, | 2739 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, |
2746 | elems.ssid, elems.ssid_len); | 2740 | elems->ssid, elems->ssid_len); |
2747 | if (!bss) | 2741 | if (!bss) |
2748 | return; | 2742 | return; |
2749 | } else { | 2743 | } else { |
@@ -2756,43 +2750,43 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2756 | } | 2750 | } |
2757 | 2751 | ||
2758 | /* save the ERP value so that it is available at association time */ | 2752 | /* save the ERP value so that it is available at association time */ |
2759 | if (elems.erp_info && elems.erp_info_len >= 1) { | 2753 | if (elems->erp_info && elems->erp_info_len >= 1) { |
2760 | bss->erp_value = elems.erp_info[0]; | 2754 | bss->erp_value = elems->erp_info[0]; |
2761 | bss->has_erp_value = 1; | 2755 | bss->has_erp_value = 1; |
2762 | } | 2756 | } |
2763 | 2757 | ||
2764 | if (elems.ht_cap_elem && | 2758 | if (elems->ht_cap_elem && |
2765 | (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len || | 2759 | (!bss->ht_ie || bss->ht_ie_len != elems->ht_cap_elem_len || |
2766 | memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) { | 2760 | memcmp(bss->ht_ie, elems->ht_cap_elem, elems->ht_cap_elem_len))) { |
2767 | kfree(bss->ht_ie); | 2761 | kfree(bss->ht_ie); |
2768 | bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC); | 2762 | bss->ht_ie = kmalloc(elems->ht_cap_elem_len + 2, GFP_ATOMIC); |
2769 | if (bss->ht_ie) { | 2763 | if (bss->ht_ie) { |
2770 | memcpy(bss->ht_ie, elems.ht_cap_elem - 2, | 2764 | memcpy(bss->ht_ie, elems->ht_cap_elem - 2, |
2771 | elems.ht_cap_elem_len + 2); | 2765 | elems->ht_cap_elem_len + 2); |
2772 | bss->ht_ie_len = elems.ht_cap_elem_len + 2; | 2766 | bss->ht_ie_len = elems->ht_cap_elem_len + 2; |
2773 | } else | 2767 | } else |
2774 | bss->ht_ie_len = 0; | 2768 | bss->ht_ie_len = 0; |
2775 | } else if (!elems.ht_cap_elem && bss->ht_ie) { | 2769 | } else if (!elems->ht_cap_elem && bss->ht_ie) { |
2776 | kfree(bss->ht_ie); | 2770 | kfree(bss->ht_ie); |
2777 | bss->ht_ie = NULL; | 2771 | bss->ht_ie = NULL; |
2778 | bss->ht_ie_len = 0; | 2772 | bss->ht_ie_len = 0; |
2779 | } | 2773 | } |
2780 | 2774 | ||
2781 | if (elems.ht_info_elem && | 2775 | if (elems->ht_info_elem && |
2782 | (!bss->ht_add_ie || | 2776 | (!bss->ht_add_ie || |
2783 | bss->ht_add_ie_len != elems.ht_info_elem_len || | 2777 | bss->ht_add_ie_len != elems->ht_info_elem_len || |
2784 | memcmp(bss->ht_add_ie, elems.ht_info_elem, | 2778 | memcmp(bss->ht_add_ie, elems->ht_info_elem, |
2785 | elems.ht_info_elem_len))) { | 2779 | elems->ht_info_elem_len))) { |
2786 | kfree(bss->ht_add_ie); | 2780 | kfree(bss->ht_add_ie); |
2787 | bss->ht_add_ie = | 2781 | bss->ht_add_ie = |
2788 | kmalloc(elems.ht_info_elem_len + 2, GFP_ATOMIC); | 2782 | kmalloc(elems->ht_info_elem_len + 2, GFP_ATOMIC); |
2789 | if (bss->ht_add_ie) { | 2783 | if (bss->ht_add_ie) { |
2790 | memcpy(bss->ht_add_ie, elems.ht_info_elem - 2, | 2784 | memcpy(bss->ht_add_ie, elems->ht_info_elem - 2, |
2791 | elems.ht_info_elem_len + 2); | 2785 | elems->ht_info_elem_len + 2); |
2792 | bss->ht_add_ie_len = elems.ht_info_elem_len + 2; | 2786 | bss->ht_add_ie_len = elems->ht_info_elem_len + 2; |
2793 | } else | 2787 | } else |
2794 | bss->ht_add_ie_len = 0; | 2788 | bss->ht_add_ie_len = 0; |
2795 | } else if (!elems.ht_info_elem && bss->ht_add_ie) { | 2789 | } else if (!elems->ht_info_elem && bss->ht_add_ie) { |
2796 | kfree(bss->ht_add_ie); | 2790 | kfree(bss->ht_add_ie); |
2797 | bss->ht_add_ie = NULL; | 2791 | bss->ht_add_ie = NULL; |
2798 | bss->ht_add_ie_len = 0; | 2792 | bss->ht_add_ie_len = 0; |
@@ -2802,20 +2796,20 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2802 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); | 2796 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); |
2803 | 2797 | ||
2804 | bss->supp_rates_len = 0; | 2798 | bss->supp_rates_len = 0; |
2805 | if (elems.supp_rates) { | 2799 | if (elems->supp_rates) { |
2806 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 2800 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; |
2807 | if (clen > elems.supp_rates_len) | 2801 | if (clen > elems->supp_rates_len) |
2808 | clen = elems.supp_rates_len; | 2802 | clen = elems->supp_rates_len; |
2809 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems.supp_rates, | 2803 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, |
2810 | clen); | 2804 | clen); |
2811 | bss->supp_rates_len += clen; | 2805 | bss->supp_rates_len += clen; |
2812 | } | 2806 | } |
2813 | if (elems.ext_supp_rates) { | 2807 | if (elems->ext_supp_rates) { |
2814 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 2808 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; |
2815 | if (clen > elems.ext_supp_rates_len) | 2809 | if (clen > elems->ext_supp_rates_len) |
2816 | clen = elems.ext_supp_rates_len; | 2810 | clen = elems->ext_supp_rates_len; |
2817 | memcpy(&bss->supp_rates[bss->supp_rates_len], | 2811 | memcpy(&bss->supp_rates[bss->supp_rates_len], |
2818 | elems.ext_supp_rates, clen); | 2812 | elems->ext_supp_rates, clen); |
2819 | bss->supp_rates_len += clen; | 2813 | bss->supp_rates_len += clen; |
2820 | } | 2814 | } |
2821 | 2815 | ||
@@ -2839,33 +2833,33 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2839 | return; | 2833 | return; |
2840 | } | 2834 | } |
2841 | 2835 | ||
2842 | if (elems.wpa && | 2836 | if (elems->wpa && |
2843 | (!bss->wpa_ie || bss->wpa_ie_len != elems.wpa_len || | 2837 | (!bss->wpa_ie || bss->wpa_ie_len != elems->wpa_len || |
2844 | memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) { | 2838 | memcmp(bss->wpa_ie, elems->wpa, elems->wpa_len))) { |
2845 | kfree(bss->wpa_ie); | 2839 | kfree(bss->wpa_ie); |
2846 | bss->wpa_ie = kmalloc(elems.wpa_len + 2, GFP_ATOMIC); | 2840 | bss->wpa_ie = kmalloc(elems->wpa_len + 2, GFP_ATOMIC); |
2847 | if (bss->wpa_ie) { | 2841 | if (bss->wpa_ie) { |
2848 | memcpy(bss->wpa_ie, elems.wpa - 2, elems.wpa_len + 2); | 2842 | memcpy(bss->wpa_ie, elems->wpa - 2, elems->wpa_len + 2); |
2849 | bss->wpa_ie_len = elems.wpa_len + 2; | 2843 | bss->wpa_ie_len = elems->wpa_len + 2; |
2850 | } else | 2844 | } else |
2851 | bss->wpa_ie_len = 0; | 2845 | bss->wpa_ie_len = 0; |
2852 | } else if (!elems.wpa && bss->wpa_ie) { | 2846 | } else if (!elems->wpa && bss->wpa_ie) { |
2853 | kfree(bss->wpa_ie); | 2847 | kfree(bss->wpa_ie); |
2854 | bss->wpa_ie = NULL; | 2848 | bss->wpa_ie = NULL; |
2855 | bss->wpa_ie_len = 0; | 2849 | bss->wpa_ie_len = 0; |
2856 | } | 2850 | } |
2857 | 2851 | ||
2858 | if (elems.rsn && | 2852 | if (elems->rsn && |
2859 | (!bss->rsn_ie || bss->rsn_ie_len != elems.rsn_len || | 2853 | (!bss->rsn_ie || bss->rsn_ie_len != elems->rsn_len || |
2860 | memcmp(bss->rsn_ie, elems.rsn, elems.rsn_len))) { | 2854 | memcmp(bss->rsn_ie, elems->rsn, elems->rsn_len))) { |
2861 | kfree(bss->rsn_ie); | 2855 | kfree(bss->rsn_ie); |
2862 | bss->rsn_ie = kmalloc(elems.rsn_len + 2, GFP_ATOMIC); | 2856 | bss->rsn_ie = kmalloc(elems->rsn_len + 2, GFP_ATOMIC); |
2863 | if (bss->rsn_ie) { | 2857 | if (bss->rsn_ie) { |
2864 | memcpy(bss->rsn_ie, elems.rsn - 2, elems.rsn_len + 2); | 2858 | memcpy(bss->rsn_ie, elems->rsn - 2, elems->rsn_len + 2); |
2865 | bss->rsn_ie_len = elems.rsn_len + 2; | 2859 | bss->rsn_ie_len = elems->rsn_len + 2; |
2866 | } else | 2860 | } else |
2867 | bss->rsn_ie_len = 0; | 2861 | bss->rsn_ie_len = 0; |
2868 | } else if (!elems.rsn && bss->rsn_ie) { | 2862 | } else if (!elems->rsn && bss->rsn_ie) { |
2869 | kfree(bss->rsn_ie); | 2863 | kfree(bss->rsn_ie); |
2870 | bss->rsn_ie = NULL; | 2864 | bss->rsn_ie = NULL; |
2871 | bss->rsn_ie_len = 0; | 2865 | bss->rsn_ie_len = 0; |
@@ -2885,20 +2879,21 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2885 | * inclusion of the WMM Parameters in beacons, however, is optional. | 2879 | * inclusion of the WMM Parameters in beacons, however, is optional. |
2886 | */ | 2880 | */ |
2887 | 2881 | ||
2888 | if (elems.wmm_param && | 2882 | if (elems->wmm_param && |
2889 | (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_param_len || | 2883 | (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_param_len || |
2890 | memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) { | 2884 | memcmp(bss->wmm_ie, elems->wmm_param, elems->wmm_param_len))) { |
2891 | kfree(bss->wmm_ie); | 2885 | kfree(bss->wmm_ie); |
2892 | bss->wmm_ie = kmalloc(elems.wmm_param_len + 2, GFP_ATOMIC); | 2886 | bss->wmm_ie = kmalloc(elems->wmm_param_len + 2, GFP_ATOMIC); |
2893 | if (bss->wmm_ie) { | 2887 | if (bss->wmm_ie) { |
2894 | memcpy(bss->wmm_ie, elems.wmm_param - 2, | 2888 | memcpy(bss->wmm_ie, elems->wmm_param - 2, |
2895 | elems.wmm_param_len + 2); | 2889 | elems->wmm_param_len + 2); |
2896 | bss->wmm_ie_len = elems.wmm_param_len + 2; | 2890 | bss->wmm_ie_len = elems->wmm_param_len + 2; |
2897 | } else | 2891 | } else |
2898 | bss->wmm_ie_len = 0; | 2892 | bss->wmm_ie_len = 0; |
2899 | } else if (elems.wmm_info && | 2893 | } else if (elems->wmm_info && |
2900 | (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_info_len || | 2894 | (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_info_len || |
2901 | memcmp(bss->wmm_ie, elems.wmm_info, elems.wmm_info_len))) { | 2895 | memcmp(bss->wmm_ie, elems->wmm_info, |
2896 | elems->wmm_info_len))) { | ||
2902 | /* As for certain AP's Fifth bit is not set in WMM IE in | 2897 | /* As for certain AP's Fifth bit is not set in WMM IE in |
2903 | * beacon frames.So while parsing the beacon frame the | 2898 | * beacon frames.So while parsing the beacon frame the |
2904 | * wmm_info structure is used instead of wmm_param. | 2899 | * wmm_info structure is used instead of wmm_param. |
@@ -2908,14 +2903,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2908 | * n-band association. | 2903 | * n-band association. |
2909 | */ | 2904 | */ |
2910 | kfree(bss->wmm_ie); | 2905 | kfree(bss->wmm_ie); |
2911 | bss->wmm_ie = kmalloc(elems.wmm_info_len + 2, GFP_ATOMIC); | 2906 | bss->wmm_ie = kmalloc(elems->wmm_info_len + 2, GFP_ATOMIC); |
2912 | if (bss->wmm_ie) { | 2907 | if (bss->wmm_ie) { |
2913 | memcpy(bss->wmm_ie, elems.wmm_info - 2, | 2908 | memcpy(bss->wmm_ie, elems->wmm_info - 2, |
2914 | elems.wmm_info_len + 2); | 2909 | elems->wmm_info_len + 2); |
2915 | bss->wmm_ie_len = elems.wmm_info_len + 2; | 2910 | bss->wmm_ie_len = elems->wmm_info_len + 2; |
2916 | } else | 2911 | } else |
2917 | bss->wmm_ie_len = 0; | 2912 | bss->wmm_ie_len = 0; |
2918 | } else if (!elems.wmm_param && !elems.wmm_info && bss->wmm_ie) { | 2913 | } else if (!elems->wmm_param && !elems->wmm_info && bss->wmm_ie) { |
2919 | kfree(bss->wmm_ie); | 2914 | kfree(bss->wmm_ie); |
2920 | bss->wmm_ie = NULL; | 2915 | bss->wmm_ie = NULL; |
2921 | bss->wmm_ie_len = 0; | 2916 | bss->wmm_ie_len = 0; |
@@ -2926,8 +2921,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2926 | !local->sta_sw_scanning && !local->sta_hw_scanning && | 2921 | !local->sta_sw_scanning && !local->sta_hw_scanning && |
2927 | bss->capability & WLAN_CAPABILITY_IBSS && | 2922 | bss->capability & WLAN_CAPABILITY_IBSS && |
2928 | bss->freq == local->oper_channel->center_freq && | 2923 | bss->freq == local->oper_channel->center_freq && |
2929 | elems.ssid_len == sdata->u.sta.ssid_len && | 2924 | elems->ssid_len == sdata->u.sta.ssid_len && |
2930 | memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) { | 2925 | memcmp(elems->ssid, sdata->u.sta.ssid, |
2926 | sdata->u.sta.ssid_len) == 0) { | ||
2931 | if (rx_status->flag & RX_FLAG_TSFT) { | 2927 | if (rx_status->flag & RX_FLAG_TSFT) { |
2932 | /* in order for correct IBSS merging we need mactime | 2928 | /* in order for correct IBSS merging we need mactime |
2933 | * | 2929 | * |
@@ -2986,7 +2982,17 @@ static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev, | |||
2986 | size_t len, | 2982 | size_t len, |
2987 | struct ieee80211_rx_status *rx_status) | 2983 | struct ieee80211_rx_status *rx_status) |
2988 | { | 2984 | { |
2989 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 0); | 2985 | size_t baselen; |
2986 | struct ieee802_11_elems elems; | ||
2987 | |||
2988 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | ||
2989 | if (baselen > len) | ||
2990 | return; | ||
2991 | |||
2992 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | ||
2993 | &elems); | ||
2994 | |||
2995 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 0); | ||
2990 | } | 2996 | } |
2991 | 2997 | ||
2992 | 2998 | ||
@@ -3003,7 +3009,14 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
3003 | struct ieee80211_conf *conf = &local->hw.conf; | 3009 | struct ieee80211_conf *conf = &local->hw.conf; |
3004 | u32 changed = 0; | 3010 | u32 changed = 0; |
3005 | 3011 | ||
3006 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1); | 3012 | /* Process beacon from the current BSS */ |
3013 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
3014 | if (baselen > len) | ||
3015 | return; | ||
3016 | |||
3017 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
3018 | |||
3019 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 1); | ||
3007 | 3020 | ||
3008 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3021 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3009 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | 3022 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) |
@@ -3014,13 +3027,6 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
3014 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) | 3027 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) |
3015 | return; | 3028 | return; |
3016 | 3029 | ||
3017 | /* Process beacon from the current BSS */ | ||
3018 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
3019 | if (baselen > len) | ||
3020 | return; | ||
3021 | |||
3022 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
3023 | |||
3024 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 3030 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
3025 | elems.wmm_param_len); | 3031 | elems.wmm_param_len); |
3026 | 3032 | ||