From ae6a44e3afae0e813e9ab707a2317b08e21f4ab2 Mon Sep 17 00:00:00 2001 From: Ester Kummer Date: Fri, 27 Jun 2008 18:54:48 +0300 Subject: [PATCH] mac80211: removing duplicated parsing of information elements This patch removes the duplicated parsing of information elements in ieee80211_rx_bss_info and in ieee_rx_mgmt_beacon Signed-off-by: Tomas Winkler Signed-off-by: Ester Kummer Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 188 +++++++++++++++++++++++--------------------- 1 file 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, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_rx_status *rx_status, + struct ieee802_11_elems *elems, int beacon) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee802_11_elems elems; - size_t baselen; int freq, clen; struct ieee80211_sta_bss *bss; struct sta_info *sta; @@ -2669,29 +2668,24 @@ static void ieee80211_rx_bss_info(struct net_device *dev, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da)); #endif - baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; - if (baselen > len) - return; - beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); - ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); - if (ieee80211_vif_is_mesh(&sdata->vif) && elems.mesh_id && - elems.mesh_config && mesh_matches_local(&elems, dev)) { - u64 rates = ieee80211_sta_get_rates(local, &elems, + if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id && + elems->mesh_config && mesh_matches_local(elems, dev)) { + u64 rates = ieee80211_sta_get_rates(local, elems, rx_status->band); mesh_neighbour_update(mgmt->sa, rates, dev, - mesh_peer_accepts_plinks(&elems, dev)); + mesh_peer_accepts_plinks(elems, dev)); } rcu_read_lock(); - if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && + if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates && memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && (sta = sta_info_get(local, mgmt->sa))) { u64 prev_rates; - u64 supp_rates = ieee80211_sta_get_rates(local, &elems, + u64 supp_rates = ieee80211_sta_get_rates(local, elems, rx_status->band); prev_rates = sta->supp_rates[rx_status->band]; @@ -2716,8 +2710,8 @@ static void ieee80211_rx_bss_info(struct net_device *dev, rcu_read_unlock(); - if (elems.ds_params && elems.ds_params_len == 1) - freq = ieee80211_channel_to_frequency(elems.ds_params[0]); + if (elems->ds_params && elems->ds_params_len == 1) + freq = ieee80211_channel_to_frequency(elems->ds_params[0]); else freq = rx_status->freq; @@ -2727,23 +2721,23 @@ static void ieee80211_rx_bss_info(struct net_device *dev, return; #ifdef CONFIG_MAC80211_MESH - if (elems.mesh_config) - bss = ieee80211_rx_mesh_bss_get(dev, elems.mesh_id, - elems.mesh_id_len, elems.mesh_config, freq); + if (elems->mesh_config) + bss = ieee80211_rx_mesh_bss_get(dev, elems->mesh_id, + elems->mesh_id_len, elems->mesh_config, freq); else #endif bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, - elems.ssid, elems.ssid_len); + elems->ssid, elems->ssid_len); if (!bss) { #ifdef CONFIG_MAC80211_MESH - if (elems.mesh_config) - bss = ieee80211_rx_mesh_bss_add(dev, elems.mesh_id, - elems.mesh_id_len, elems.mesh_config, - elems.mesh_config_len, freq); + if (elems->mesh_config) + bss = ieee80211_rx_mesh_bss_add(dev, elems->mesh_id, + elems->mesh_id_len, elems->mesh_config, + elems->mesh_config_len, freq); else #endif bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, - elems.ssid, elems.ssid_len); + elems->ssid, elems->ssid_len); if (!bss) return; } else { @@ -2756,43 +2750,43 @@ static void ieee80211_rx_bss_info(struct net_device *dev, } /* save the ERP value so that it is available at association time */ - if (elems.erp_info && elems.erp_info_len >= 1) { - bss->erp_value = elems.erp_info[0]; + if (elems->erp_info && elems->erp_info_len >= 1) { + bss->erp_value = elems->erp_info[0]; bss->has_erp_value = 1; } - if (elems.ht_cap_elem && - (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len || - memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) { + if (elems->ht_cap_elem && + (!bss->ht_ie || bss->ht_ie_len != elems->ht_cap_elem_len || + memcmp(bss->ht_ie, elems->ht_cap_elem, elems->ht_cap_elem_len))) { kfree(bss->ht_ie); - bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC); + bss->ht_ie = kmalloc(elems->ht_cap_elem_len + 2, GFP_ATOMIC); if (bss->ht_ie) { - memcpy(bss->ht_ie, elems.ht_cap_elem - 2, - elems.ht_cap_elem_len + 2); - bss->ht_ie_len = elems.ht_cap_elem_len + 2; + memcpy(bss->ht_ie, elems->ht_cap_elem - 2, + elems->ht_cap_elem_len + 2); + bss->ht_ie_len = elems->ht_cap_elem_len + 2; } else bss->ht_ie_len = 0; - } else if (!elems.ht_cap_elem && bss->ht_ie) { + } else if (!elems->ht_cap_elem && bss->ht_ie) { kfree(bss->ht_ie); bss->ht_ie = NULL; bss->ht_ie_len = 0; } - if (elems.ht_info_elem && + if (elems->ht_info_elem && (!bss->ht_add_ie || - bss->ht_add_ie_len != elems.ht_info_elem_len || - memcmp(bss->ht_add_ie, elems.ht_info_elem, - elems.ht_info_elem_len))) { + bss->ht_add_ie_len != elems->ht_info_elem_len || + memcmp(bss->ht_add_ie, elems->ht_info_elem, + elems->ht_info_elem_len))) { kfree(bss->ht_add_ie); bss->ht_add_ie = - kmalloc(elems.ht_info_elem_len + 2, GFP_ATOMIC); + kmalloc(elems->ht_info_elem_len + 2, GFP_ATOMIC); if (bss->ht_add_ie) { - memcpy(bss->ht_add_ie, elems.ht_info_elem - 2, - elems.ht_info_elem_len + 2); - bss->ht_add_ie_len = elems.ht_info_elem_len + 2; + memcpy(bss->ht_add_ie, elems->ht_info_elem - 2, + elems->ht_info_elem_len + 2); + bss->ht_add_ie_len = elems->ht_info_elem_len + 2; } else bss->ht_add_ie_len = 0; - } else if (!elems.ht_info_elem && bss->ht_add_ie) { + } else if (!elems->ht_info_elem && bss->ht_add_ie) { kfree(bss->ht_add_ie); bss->ht_add_ie = NULL; bss->ht_add_ie_len = 0; @@ -2802,20 +2796,20 @@ static void ieee80211_rx_bss_info(struct net_device *dev, bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); bss->supp_rates_len = 0; - if (elems.supp_rates) { + if (elems->supp_rates) { clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; - if (clen > elems.supp_rates_len) - clen = elems.supp_rates_len; - memcpy(&bss->supp_rates[bss->supp_rates_len], elems.supp_rates, + if (clen > elems->supp_rates_len) + clen = elems->supp_rates_len; + memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, clen); bss->supp_rates_len += clen; } - if (elems.ext_supp_rates) { + if (elems->ext_supp_rates) { clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; - if (clen > elems.ext_supp_rates_len) - clen = elems.ext_supp_rates_len; + if (clen > elems->ext_supp_rates_len) + clen = elems->ext_supp_rates_len; memcpy(&bss->supp_rates[bss->supp_rates_len], - elems.ext_supp_rates, clen); + elems->ext_supp_rates, clen); bss->supp_rates_len += clen; } @@ -2839,33 +2833,33 @@ static void ieee80211_rx_bss_info(struct net_device *dev, return; } - if (elems.wpa && - (!bss->wpa_ie || bss->wpa_ie_len != elems.wpa_len || - memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) { + if (elems->wpa && + (!bss->wpa_ie || bss->wpa_ie_len != elems->wpa_len || + memcmp(bss->wpa_ie, elems->wpa, elems->wpa_len))) { kfree(bss->wpa_ie); - bss->wpa_ie = kmalloc(elems.wpa_len + 2, GFP_ATOMIC); + bss->wpa_ie = kmalloc(elems->wpa_len + 2, GFP_ATOMIC); if (bss->wpa_ie) { - memcpy(bss->wpa_ie, elems.wpa - 2, elems.wpa_len + 2); - bss->wpa_ie_len = elems.wpa_len + 2; + memcpy(bss->wpa_ie, elems->wpa - 2, elems->wpa_len + 2); + bss->wpa_ie_len = elems->wpa_len + 2; } else bss->wpa_ie_len = 0; - } else if (!elems.wpa && bss->wpa_ie) { + } else if (!elems->wpa && bss->wpa_ie) { kfree(bss->wpa_ie); bss->wpa_ie = NULL; bss->wpa_ie_len = 0; } - if (elems.rsn && - (!bss->rsn_ie || bss->rsn_ie_len != elems.rsn_len || - memcmp(bss->rsn_ie, elems.rsn, elems.rsn_len))) { + if (elems->rsn && + (!bss->rsn_ie || bss->rsn_ie_len != elems->rsn_len || + memcmp(bss->rsn_ie, elems->rsn, elems->rsn_len))) { kfree(bss->rsn_ie); - bss->rsn_ie = kmalloc(elems.rsn_len + 2, GFP_ATOMIC); + bss->rsn_ie = kmalloc(elems->rsn_len + 2, GFP_ATOMIC); if (bss->rsn_ie) { - memcpy(bss->rsn_ie, elems.rsn - 2, elems.rsn_len + 2); - bss->rsn_ie_len = elems.rsn_len + 2; + memcpy(bss->rsn_ie, elems->rsn - 2, elems->rsn_len + 2); + bss->rsn_ie_len = elems->rsn_len + 2; } else bss->rsn_ie_len = 0; - } else if (!elems.rsn && bss->rsn_ie) { + } else if (!elems->rsn && bss->rsn_ie) { kfree(bss->rsn_ie); bss->rsn_ie = NULL; bss->rsn_ie_len = 0; @@ -2885,20 +2879,21 @@ static void ieee80211_rx_bss_info(struct net_device *dev, * inclusion of the WMM Parameters in beacons, however, is optional. */ - if (elems.wmm_param && - (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_param_len || - memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) { + if (elems->wmm_param && + (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_param_len || + memcmp(bss->wmm_ie, elems->wmm_param, elems->wmm_param_len))) { kfree(bss->wmm_ie); - bss->wmm_ie = kmalloc(elems.wmm_param_len + 2, GFP_ATOMIC); + bss->wmm_ie = kmalloc(elems->wmm_param_len + 2, GFP_ATOMIC); if (bss->wmm_ie) { - memcpy(bss->wmm_ie, elems.wmm_param - 2, - elems.wmm_param_len + 2); - bss->wmm_ie_len = elems.wmm_param_len + 2; + memcpy(bss->wmm_ie, elems->wmm_param - 2, + elems->wmm_param_len + 2); + bss->wmm_ie_len = elems->wmm_param_len + 2; } else bss->wmm_ie_len = 0; - } else if (elems.wmm_info && - (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_info_len || - memcmp(bss->wmm_ie, elems.wmm_info, elems.wmm_info_len))) { + } else if (elems->wmm_info && + (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_info_len || + memcmp(bss->wmm_ie, elems->wmm_info, + elems->wmm_info_len))) { /* As for certain AP's Fifth bit is not set in WMM IE in * beacon frames.So while parsing the beacon frame the * wmm_info structure is used instead of wmm_param. @@ -2908,14 +2903,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, * n-band association. */ kfree(bss->wmm_ie); - bss->wmm_ie = kmalloc(elems.wmm_info_len + 2, GFP_ATOMIC); + bss->wmm_ie = kmalloc(elems->wmm_info_len + 2, GFP_ATOMIC); if (bss->wmm_ie) { - memcpy(bss->wmm_ie, elems.wmm_info - 2, - elems.wmm_info_len + 2); - bss->wmm_ie_len = elems.wmm_info_len + 2; + memcpy(bss->wmm_ie, elems->wmm_info - 2, + elems->wmm_info_len + 2); + bss->wmm_ie_len = elems->wmm_info_len + 2; } else bss->wmm_ie_len = 0; - } else if (!elems.wmm_param && !elems.wmm_info && bss->wmm_ie) { + } else if (!elems->wmm_param && !elems->wmm_info && bss->wmm_ie) { kfree(bss->wmm_ie); bss->wmm_ie = NULL; bss->wmm_ie_len = 0; @@ -2926,8 +2921,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, !local->sta_sw_scanning && !local->sta_hw_scanning && bss->capability & WLAN_CAPABILITY_IBSS && bss->freq == local->oper_channel->center_freq && - elems.ssid_len == sdata->u.sta.ssid_len && - memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) { + elems->ssid_len == sdata->u.sta.ssid_len && + memcmp(elems->ssid, sdata->u.sta.ssid, + sdata->u.sta.ssid_len) == 0) { if (rx_status->flag & RX_FLAG_TSFT) { /* in order for correct IBSS merging we need mactime * @@ -2986,7 +2982,17 @@ static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev, size_t len, struct ieee80211_rx_status *rx_status) { - ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 0); + size_t baselen; + struct ieee802_11_elems elems; + + baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; + if (baselen > len) + return; + + ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, + &elems); + + ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 0); } @@ -3003,7 +3009,14 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, struct ieee80211_conf *conf = &local->hw.conf; u32 changed = 0; - ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1); + /* Process beacon from the current BSS */ + baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; + if (baselen > len) + return; + + ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); + + ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 1); sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (sdata->vif.type != IEEE80211_IF_TYPE_STA) @@ -3014,13 +3027,6 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) return; - /* Process beacon from the current BSS */ - baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; - if (baselen > len) - return; - - ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); - ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, elems.wmm_param_len); -- 2.30.2