diff options
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r-- | net/mac80211/ibss.c | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 5746d62faba1..5f3620f0bc0a 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -109,7 +109,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
109 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | 109 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
110 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 110 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
111 | IEEE80211_STYPE_PROBE_RESP); | 111 | IEEE80211_STYPE_PROBE_RESP); |
112 | memset(mgmt->da, 0xff, ETH_ALEN); | 112 | eth_broadcast_addr(mgmt->da); |
113 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 113 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
114 | memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); | 114 | memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); |
115 | mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int); | 115 | mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int); |
@@ -205,7 +205,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
205 | mod_timer(&ifibss->timer, | 205 | mod_timer(&ifibss->timer, |
206 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); | 206 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); |
207 | 207 | ||
208 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, | 208 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan, |
209 | mgmt, skb->len, 0, GFP_KERNEL); | 209 | mgmt, skb->len, 0, GFP_KERNEL); |
210 | cfg80211_put_bss(bss); | 210 | cfg80211_put_bss(bss); |
211 | netif_carrier_on(sdata->dev); | 211 | netif_carrier_on(sdata->dev); |
@@ -278,7 +278,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | |||
278 | if (auth && !sdata->u.ibss.auth_frame_registrations) { | 278 | if (auth && !sdata->u.ibss.auth_frame_registrations) { |
279 | ibss_dbg(sdata, | 279 | ibss_dbg(sdata, |
280 | "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", | 280 | "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", |
281 | sdata->vif.addr, sdata->u.ibss.bssid, addr); | 281 | sdata->vif.addr, addr, sdata->u.ibss.bssid); |
282 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, | 282 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, |
283 | addr, sdata->u.ibss.bssid, NULL, 0, 0); | 283 | addr, sdata->u.ibss.bssid, NULL, 0, 0); |
284 | } | 284 | } |
@@ -294,7 +294,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
294 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 294 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
295 | struct ieee80211_local *local = sdata->local; | 295 | struct ieee80211_local *local = sdata->local; |
296 | struct sta_info *sta; | 296 | struct sta_info *sta; |
297 | int band = local->hw.conf.channel->band; | 297 | int band = local->oper_channel->band; |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * XXX: Consider removing the least recently used entry and | 300 | * XXX: Consider removing the least recently used entry and |
@@ -332,11 +332,27 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
332 | return ieee80211_ibss_finish_sta(sta, auth); | 332 | return ieee80211_ibss_finish_sta(sta, auth); |
333 | } | 333 | } |
334 | 334 | ||
335 | static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata, | ||
336 | struct ieee80211_mgmt *mgmt, | ||
337 | size_t len) | ||
338 | { | ||
339 | u16 reason = le16_to_cpu(mgmt->u.deauth.reason_code); | ||
340 | |||
341 | if (len < IEEE80211_DEAUTH_FRAME_LEN) | ||
342 | return; | ||
343 | |||
344 | ibss_dbg(sdata, "RX DeAuth SA=%pM DA=%pM BSSID=%pM (reason: %d)\n", | ||
345 | mgmt->sa, mgmt->da, mgmt->bssid, reason); | ||
346 | sta_info_destroy_addr(sdata, mgmt->sa); | ||
347 | } | ||
348 | |||
335 | static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | 349 | static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, |
336 | struct ieee80211_mgmt *mgmt, | 350 | struct ieee80211_mgmt *mgmt, |
337 | size_t len) | 351 | size_t len) |
338 | { | 352 | { |
339 | u16 auth_alg, auth_transaction; | 353 | u16 auth_alg, auth_transaction; |
354 | struct sta_info *sta; | ||
355 | u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | ||
340 | 356 | ||
341 | lockdep_assert_held(&sdata->u.ibss.mtx); | 357 | lockdep_assert_held(&sdata->u.ibss.mtx); |
342 | 358 | ||
@@ -352,10 +368,22 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
352 | "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", | 368 | "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", |
353 | mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); | 369 | mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); |
354 | sta_info_destroy_addr(sdata, mgmt->sa); | 370 | sta_info_destroy_addr(sdata, mgmt->sa); |
355 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); | 371 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); |
356 | rcu_read_unlock(); | 372 | rcu_read_unlock(); |
357 | 373 | ||
358 | /* | 374 | /* |
375 | * if we have any problem in allocating the new station, we reply with a | ||
376 | * DEAUTH frame to tell the other end that we had a problem | ||
377 | */ | ||
378 | if (!sta) { | ||
379 | ieee80211_send_deauth_disassoc(sdata, sdata->u.ibss.bssid, | ||
380 | IEEE80211_STYPE_DEAUTH, | ||
381 | WLAN_REASON_UNSPECIFIED, true, | ||
382 | deauth_frame_buf); | ||
383 | return; | ||
384 | } | ||
385 | |||
386 | /* | ||
359 | * IEEE 802.11 standard does not require authentication in IBSS | 387 | * IEEE 802.11 standard does not require authentication in IBSS |
360 | * networks and most implementations do not seem to use it. | 388 | * networks and most implementations do not seem to use it. |
361 | * However, try to reply to authentication attempts if someone | 389 | * However, try to reply to authentication attempts if someone |
@@ -459,8 +487,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
459 | } | 487 | } |
460 | } | 488 | } |
461 | 489 | ||
462 | if (sta && rates_updated) | 490 | if (sta && rates_updated) { |
491 | drv_sta_rc_update(local, sdata, &sta->sta, | ||
492 | IEEE80211_RC_SUPP_RATES_CHANGED); | ||
463 | rate_control_rate_init(sta); | 493 | rate_control_rate_init(sta); |
494 | } | ||
464 | 495 | ||
465 | rcu_read_unlock(); | 496 | rcu_read_unlock(); |
466 | } | 497 | } |
@@ -561,7 +592,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, | |||
561 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 592 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
562 | struct ieee80211_local *local = sdata->local; | 593 | struct ieee80211_local *local = sdata->local; |
563 | struct sta_info *sta; | 594 | struct sta_info *sta; |
564 | int band = local->hw.conf.channel->band; | 595 | int band = local->oper_channel->band; |
565 | 596 | ||
566 | /* | 597 | /* |
567 | * XXX: Consider removing the least recently used entry and | 598 | * XXX: Consider removing the least recently used entry and |
@@ -759,7 +790,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
759 | return; | 790 | return; |
760 | } | 791 | } |
761 | sdata_info(sdata, "IBSS not allowed on %d MHz\n", | 792 | sdata_info(sdata, "IBSS not allowed on %d MHz\n", |
762 | local->hw.conf.channel->center_freq); | 793 | local->oper_channel->center_freq); |
763 | 794 | ||
764 | /* No IBSS found - decrease scan interval and continue | 795 | /* No IBSS found - decrease scan interval and continue |
765 | * scanning. */ | 796 | * scanning. */ |
@@ -899,6 +930,9 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
899 | case IEEE80211_STYPE_AUTH: | 930 | case IEEE80211_STYPE_AUTH: |
900 | ieee80211_rx_mgmt_auth_ibss(sdata, mgmt, skb->len); | 931 | ieee80211_rx_mgmt_auth_ibss(sdata, mgmt, skb->len); |
901 | break; | 932 | break; |
933 | case IEEE80211_STYPE_DEAUTH: | ||
934 | ieee80211_rx_mgmt_deauth_ibss(sdata, mgmt, skb->len); | ||
935 | break; | ||
902 | } | 936 | } |
903 | 937 | ||
904 | mgmt_out: | 938 | mgmt_out: |