aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c213
1 files changed, 73 insertions, 140 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c5991ec047be..c51860f66731 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -55,10 +55,10 @@ static u8 *ieee80211_bss_get_ie(struct ieee80211_bss *bss, u8 ie)
55{ 55{
56 u8 *end, *pos; 56 u8 *end, *pos;
57 57
58 pos = bss->ies; 58 pos = bss->cbss.information_elements;
59 if (pos == NULL) 59 if (pos == NULL)
60 return NULL; 60 return NULL;
61 end = pos + bss->ies_len; 61 end = pos + bss->cbss.len_information_elements;
62 62
63 while (pos + 1 < end) { 63 while (pos + 1 < end) {
64 if (pos + 2 + pos[1] > end) 64 if (pos + 2 + pos[1] > end)
@@ -289,7 +289,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
289 local->hw.conf.channel->center_freq, 289 local->hw.conf.channel->center_freq,
290 ifsta->ssid, ifsta->ssid_len); 290 ifsta->ssid, ifsta->ssid_len);
291 if (bss) { 291 if (bss) {
292 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 292 if (bss->cbss.capability & WLAN_CAPABILITY_PRIVACY)
293 capab |= WLAN_CAPABILITY_PRIVACY; 293 capab |= WLAN_CAPABILITY_PRIVACY;
294 if (bss->wmm_used) 294 if (bss->wmm_used)
295 wmm = 1; 295 wmm = 1;
@@ -300,7 +300,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
300 * b-only mode) */ 300 * b-only mode) */
301 rates_len = ieee80211_compatible_rates(bss, sband, &rates); 301 rates_len = ieee80211_compatible_rates(bss, sband, &rates);
302 302
303 if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && 303 if ((bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
304 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) 304 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
305 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; 305 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
306 306
@@ -816,12 +816,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
816 ifsta->ssid, ifsta->ssid_len); 816 ifsta->ssid, ifsta->ssid_len);
817 if (bss) { 817 if (bss) {
818 /* set timing information */ 818 /* set timing information */
819 sdata->vif.bss_conf.beacon_int = bss->beacon_int; 819 sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval;
820 sdata->vif.bss_conf.timestamp = bss->timestamp; 820 sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
821 sdata->vif.bss_conf.dtim_period = bss->dtim_period; 821 sdata->vif.bss_conf.dtim_period = bss->dtim_period;
822 822
823 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 823 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
824 bss->capability, bss->has_erp_value, bss->erp_value); 824 bss->cbss.capability, bss->has_erp_value, bss->erp_value);
825 825
826 ieee80211_rx_bss_put(local, bss); 826 ieee80211_rx_bss_put(local, bss);
827 } 827 }
@@ -1041,7 +1041,7 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
1041 if (!bss) 1041 if (!bss)
1042 return 0; 1042 return 0;
1043 1043
1044 bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY); 1044 bss_privacy = !!(bss->cbss.capability & WLAN_CAPABILITY_PRIVACY);
1045 wep_privacy = !!ieee80211_sta_wep_configured(sdata); 1045 wep_privacy = !!ieee80211_sta_wep_configured(sdata);
1046 privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); 1046 privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
1047 1047
@@ -1416,8 +1416,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1416 /* Add STA entry for the AP */ 1416 /* Add STA entry for the AP */
1417 sta = sta_info_get(local, ifsta->bssid); 1417 sta = sta_info_get(local, ifsta->bssid);
1418 if (!sta) { 1418 if (!sta) {
1419 struct ieee80211_bss *bss;
1420
1421 newsta = true; 1419 newsta = true;
1422 1420
1423 sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); 1421 sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
@@ -1427,15 +1425,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1427 rcu_read_unlock(); 1425 rcu_read_unlock();
1428 return; 1426 return;
1429 } 1427 }
1430 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
1431 local->hw.conf.channel->center_freq,
1432 ifsta->ssid, ifsta->ssid_len);
1433 if (bss) {
1434 sta->last_signal = bss->signal;
1435 sta->last_qual = bss->qual;
1436 sta->last_noise = bss->noise;
1437 ieee80211_rx_bss_put(local, bss);
1438 }
1439 1428
1440 /* update new sta with its last rx activity */ 1429 /* update new sta with its last rx activity */
1441 sta->last_rx = jiffies; 1430 sta->last_rx = jiffies;
@@ -1691,10 +1680,11 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1691 struct ieee80211_bss *bss) 1680 struct ieee80211_bss *bss)
1692{ 1681{
1693 return __ieee80211_sta_join_ibss(sdata, ifsta, 1682 return __ieee80211_sta_join_ibss(sdata, ifsta,
1694 bss->bssid, bss->beacon_int, 1683 bss->cbss.bssid,
1695 bss->freq, 1684 bss->cbss.beacon_interval,
1685 bss->cbss.channel->center_freq,
1696 bss->supp_rates_len, bss->supp_rates, 1686 bss->supp_rates_len, bss->supp_rates,
1697 bss->capability); 1687 bss->cbss.capability);
1698} 1688}
1699 1689
1700static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 1690static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -1769,7 +1759,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1769 } 1759 }
1770 1760
1771 /* was just updated in ieee80211_bss_info_update */ 1761 /* was just updated in ieee80211_bss_info_update */
1772 beacon_timestamp = bss->timestamp; 1762 beacon_timestamp = bss->cbss.tsf;
1773 1763
1774 /* 1764 /*
1775 * In STA mode, the remaining parameters should not be overridden 1765 * In STA mode, the remaining parameters should not be overridden
@@ -1784,8 +1774,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1784 /* check if we need to merge IBSS */ 1774 /* check if we need to merge IBSS */
1785 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && beacon && 1775 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && beacon &&
1786 (!(sdata->u.sta.flags & IEEE80211_STA_BSSID_SET)) && 1776 (!(sdata->u.sta.flags & IEEE80211_STA_BSSID_SET)) &&
1787 bss->capability & WLAN_CAPABILITY_IBSS && 1777 bss->cbss.capability & WLAN_CAPABILITY_IBSS &&
1788 bss->freq == local->oper_channel->center_freq && 1778 bss->cbss.channel == local->oper_channel &&
1789 elems->ssid_len == sdata->u.sta.ssid_len && 1779 elems->ssid_len == sdata->u.sta.ssid_len &&
1790 memcmp(elems->ssid, sdata->u.sta.ssid, 1780 memcmp(elems->ssid, sdata->u.sta.ssid,
1791 sdata->u.sta.ssid_len) == 0) { 1781 sdata->u.sta.ssid_len) == 0) {
@@ -2230,37 +2220,6 @@ static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
2230 netif_carrier_off(sdata->dev); 2220 netif_carrier_off(sdata->dev);
2231} 2221}
2232 2222
2233
2234static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
2235 const char *ssid, int ssid_len)
2236{
2237 int tmp, hidden_ssid;
2238
2239 if (ssid_len == ifsta->ssid_len &&
2240 !memcmp(ifsta->ssid, ssid, ssid_len))
2241 return 1;
2242
2243 if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
2244 return 0;
2245
2246 hidden_ssid = 1;
2247 tmp = ssid_len;
2248 while (tmp--) {
2249 if (ssid[tmp] != '\0') {
2250 hidden_ssid = 0;
2251 break;
2252 }
2253 }
2254
2255 if (hidden_ssid && (ifsta->ssid_len == ssid_len || ssid_len == 0))
2256 return 1;
2257
2258 if (ssid_len == 1 && ssid[0] == ' ')
2259 return 1;
2260
2261 return 0;
2262}
2263
2264static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, 2223static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
2265 struct ieee80211_if_sta *ifsta) 2224 struct ieee80211_if_sta *ifsta)
2266{ 2225{
@@ -2319,8 +2278,6 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
2319{ 2278{
2320 struct ieee80211_local *local = sdata->local; 2279 struct ieee80211_local *local = sdata->local;
2321 struct ieee80211_bss *bss; 2280 struct ieee80211_bss *bss;
2322 int found = 0;
2323 u8 bssid[ETH_ALEN];
2324 int active_ibss; 2281 int active_ibss;
2325 2282
2326 if (ifsta->ssid_len == 0) 2283 if (ifsta->ssid_len == 0)
@@ -2331,56 +2288,39 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
2331 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", 2288 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
2332 sdata->dev->name, active_ibss); 2289 sdata->dev->name, active_ibss);
2333#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2290#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2334 spin_lock_bh(&local->bss_lock); 2291
2335 list_for_each_entry(bss, &local->bss_list, list) { 2292 if (active_ibss)
2336 if (ifsta->ssid_len != bss->ssid_len || 2293 return 0;
2337 memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0 2294
2338 || !(bss->capability & WLAN_CAPABILITY_IBSS)) 2295 if (ifsta->flags & IEEE80211_STA_BSSID_SET)
2339 continue; 2296 bss = ieee80211_rx_bss_get(local, ifsta->bssid, 0,
2340 if ((ifsta->flags & IEEE80211_STA_BSSID_SET) && 2297 ifsta->ssid, ifsta->ssid_len);
2341 memcmp(ifsta->bssid, bss->bssid, ETH_ALEN) != 0) 2298 else
2342 continue; 2299 bss = (void *)cfg80211_get_ibss(local->hw.wiphy,
2343#ifdef CONFIG_MAC80211_IBSS_DEBUG 2300 NULL,
2344 printk(KERN_DEBUG " bssid=%pM found\n", bss->bssid); 2301 ifsta->ssid, ifsta->ssid_len);
2345#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2346 memcpy(bssid, bss->bssid, ETH_ALEN);
2347 found = 1;
2348 if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0)
2349 break;
2350 }
2351 spin_unlock_bh(&local->bss_lock);
2352 2302
2353#ifdef CONFIG_MAC80211_IBSS_DEBUG 2303#ifdef CONFIG_MAC80211_IBSS_DEBUG
2354 if (found) 2304 if (bss)
2355 printk(KERN_DEBUG " sta_find_ibss: selected %pM current " 2305 printk(KERN_DEBUG " sta_find_ibss: selected %pM current "
2356 "%pM\n", bssid, ifsta->bssid); 2306 "%pM\n", bss->cbss.bssid, ifsta->bssid);
2357#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2307#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2358 2308
2359 if (found && 2309 if (bss &&
2360 ((!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) || 2310 (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) ||
2361 memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0)) { 2311 memcmp(ifsta->bssid, bss->cbss.bssid, ETH_ALEN))) {
2362 int ret; 2312 int ret;
2363 int search_freq;
2364
2365 if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
2366 search_freq = bss->freq;
2367 else
2368 search_freq = local->hw.conf.channel->center_freq;
2369
2370 bss = ieee80211_rx_bss_get(local, bssid, search_freq,
2371 ifsta->ssid, ifsta->ssid_len);
2372 if (!bss)
2373 goto dont_join;
2374 2313
2375 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" 2314 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
2376 " based on configured SSID\n", 2315 " based on configured SSID\n",
2377 sdata->dev->name, bssid); 2316 sdata->dev->name, bss->cbss.bssid);
2317
2378 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); 2318 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
2379 ieee80211_rx_bss_put(local, bss); 2319 ieee80211_rx_bss_put(local, bss);
2380 return ret; 2320 return ret;
2381 } 2321 } else if (bss)
2322 ieee80211_rx_bss_put(local, bss);
2382 2323
2383dont_join:
2384#ifdef CONFIG_MAC80211_IBSS_DEBUG 2324#ifdef CONFIG_MAC80211_IBSS_DEBUG
2385 printk(KERN_DEBUG " did not try to join ibss\n"); 2325 printk(KERN_DEBUG " did not try to join ibss\n");
2386#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2326#endif /* CONFIG_MAC80211_IBSS_DEBUG */
@@ -2436,51 +2376,44 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
2436 struct ieee80211_if_sta *ifsta) 2376 struct ieee80211_if_sta *ifsta)
2437{ 2377{
2438 struct ieee80211_local *local = sdata->local; 2378 struct ieee80211_local *local = sdata->local;
2439 struct ieee80211_bss *bss, *selected = NULL; 2379 struct ieee80211_bss *bss;
2440 int top_rssi = 0, freq; 2380 u8 *bssid = ifsta->bssid, *ssid = ifsta->ssid;
2441 2381 u8 ssid_len = ifsta->ssid_len;
2442 spin_lock_bh(&local->bss_lock); 2382 u16 capa_mask = WLAN_CAPABILITY_ESS;
2443 freq = local->oper_channel->center_freq; 2383 u16 capa_val = WLAN_CAPABILITY_ESS;
2444 list_for_each_entry(bss, &local->bss_list, list) { 2384 struct ieee80211_channel *chan = local->oper_channel;
2445 if (!(bss->capability & WLAN_CAPABILITY_ESS)) 2385
2446 continue; 2386 if (ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
2447 2387 IEEE80211_STA_AUTO_BSSID_SEL |
2448 if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL | 2388 IEEE80211_STA_AUTO_CHANNEL_SEL)) {
2449 IEEE80211_STA_AUTO_BSSID_SEL | 2389 capa_mask |= WLAN_CAPABILITY_PRIVACY;
2450 IEEE80211_STA_AUTO_CHANNEL_SEL)) && 2390 if (sdata->default_key)
2451 (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^ 2391 capa_val |= WLAN_CAPABILITY_PRIVACY;
2452 !!sdata->default_key))
2453 continue;
2454
2455 if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
2456 bss->freq != freq)
2457 continue;
2458
2459 if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) &&
2460 memcmp(bss->bssid, ifsta->bssid, ETH_ALEN))
2461 continue;
2462
2463 if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
2464 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
2465 continue;
2466
2467 if (!selected || top_rssi < bss->signal) {
2468 selected = bss;
2469 top_rssi = bss->signal;
2470 }
2471 } 2392 }
2472 if (selected)
2473 atomic_inc(&selected->users);
2474 spin_unlock_bh(&local->bss_lock);
2475 2393
2476 if (selected) { 2394 if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
2477 ieee80211_set_freq(sdata, selected->freq); 2395 chan = NULL;
2396
2397 if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
2398 bssid = NULL;
2399
2400 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) {
2401 ssid = NULL;
2402 ssid_len = 0;
2403 }
2404
2405 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan,
2406 bssid, ssid, ssid_len,
2407 capa_mask, capa_val);
2408
2409 if (bss) {
2410 ieee80211_set_freq(sdata, bss->cbss.channel->center_freq);
2478 if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) 2411 if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
2479 ieee80211_sta_set_ssid(sdata, selected->ssid, 2412 ieee80211_sta_set_ssid(sdata, bss->ssid,
2480 selected->ssid_len); 2413 bss->ssid_len);
2481 ieee80211_sta_set_bssid(sdata, selected->bssid); 2414 ieee80211_sta_set_bssid(sdata, bss->cbss.bssid);
2482 ieee80211_sta_def_wmm_params(sdata, selected->supp_rates_len, 2415 ieee80211_sta_def_wmm_params(sdata, bss->supp_rates_len,
2483 selected->supp_rates); 2416 bss->supp_rates);
2484 if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED) 2417 if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED)
2485 sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED; 2418 sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED;
2486 else 2419 else
@@ -2489,14 +2422,14 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
2489 /* Send out direct probe if no probe resp was received or 2422 /* Send out direct probe if no probe resp was received or
2490 * the one we have is outdated 2423 * the one we have is outdated
2491 */ 2424 */
2492 if (!selected->last_probe_resp || 2425 if (!bss->last_probe_resp ||
2493 time_after(jiffies, selected->last_probe_resp 2426 time_after(jiffies, bss->last_probe_resp
2494 + IEEE80211_SCAN_RESULT_EXPIRE)) 2427 + IEEE80211_SCAN_RESULT_EXPIRE))
2495 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; 2428 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
2496 else 2429 else
2497 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; 2430 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
2498 2431
2499 ieee80211_rx_bss_put(local, selected); 2432 ieee80211_rx_bss_put(local, bss);
2500 ieee80211_sta_reset_auth(sdata, ifsta); 2433 ieee80211_sta_reset_auth(sdata, ifsta);
2501 return 0; 2434 return 0;
2502 } else { 2435 } else {