aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorAntonio Quartulli <ordex@autistici.org>2012-01-17 18:10:44 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-01-24 14:32:27 -0500
commit6d810f10325522cfcf498dc6d64b9f96e1f5153f (patch)
tree336d362834929cee89e8d420dc82ad8de0ae2c26 /net/mac80211
parent24dd0dd74ec8dc4abada132e380dc179459b0f77 (diff)
mac80211: in IBSS use the Auth frame to trigger STA reinsertion
In case of a node re-joining the cell the sta_info structure belonging to it is first destroyed and then reinserted. In this way its internal state is reset. The joining operation is recognised thank the Auth frame being received. This operation is helpful in case of a node being rebooted that is joining the ad-hoc cell again, before its purge timeout on other nodes expires. Signed-off-by: Antonio Quartulli <ordex@autistici.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ibss.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index a497c03c03d7..d38baa41cf6c 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -36,31 +36,6 @@
36#define IEEE80211_IBSS_MAX_STA_ENTRIES 128 36#define IEEE80211_IBSS_MAX_STA_ENTRIES 128
37 37
38 38
39static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
40 struct ieee80211_mgmt *mgmt,
41 size_t len)
42{
43 u16 auth_alg, auth_transaction;
44
45 lockdep_assert_held(&sdata->u.ibss.mtx);
46
47 if (len < 24 + 6)
48 return;
49
50 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
51 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
52
53 /*
54 * IEEE 802.11 standard does not require authentication in IBSS
55 * networks and most implementations do not seem to use it.
56 * However, try to reply to authentication attempts if someone
57 * has actually implemented this.
58 */
59 if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1)
60 ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0, mgmt->sa,
61 sdata->u.ibss.bssid, NULL, 0, 0);
62}
63
64static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 39static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
65 const u8 *bssid, const int beacon_int, 40 const u8 *bssid, const int beacon_int,
66 struct ieee80211_channel *chan, 41 struct ieee80211_channel *chan,
@@ -275,7 +250,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
275 cbss->tsf); 250 cbss->tsf);
276} 251}
277 252
278static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta) 253static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
254 bool auth)
279 __acquires(RCU) 255 __acquires(RCU)
280{ 256{
281 struct ieee80211_sub_if_data *sdata = sta->sdata; 257 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -298,20 +274,22 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
298 /* If it fails, maybe we raced another insertion? */ 274 /* If it fails, maybe we raced another insertion? */
299 if (sta_info_insert_rcu(sta)) 275 if (sta_info_insert_rcu(sta))
300 return sta_info_get(sdata, addr); 276 return sta_info_get(sdata, addr);
277 if (auth) {
301#ifdef CONFIG_MAC80211_IBSS_DEBUG 278#ifdef CONFIG_MAC80211_IBSS_DEBUG
302 printk(KERN_DEBUG "TX Auth SA=%pM DA=%pM BSSID=%pM" 279 printk(KERN_DEBUG "TX Auth SA=%pM DA=%pM BSSID=%pM"
303 "(auth_transaction=1)\n", sdata->vif.addr, 280 "(auth_transaction=1)\n", sdata->vif.addr,
304 sdata->u.ibss.bssid, addr); 281 sdata->u.ibss.bssid, addr);
305#endif 282#endif
306 ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, 283 ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0,
307 addr, sdata->u.ibss.bssid, NULL, 0, 0); 284 addr, sdata->u.ibss.bssid, NULL, 0, 0);
285 }
308 return sta; 286 return sta;
309} 287}
310 288
311static struct sta_info * 289static struct sta_info *
312ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 290ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
313 const u8 *bssid, const u8 *addr, 291 const u8 *bssid, const u8 *addr,
314 u32 supp_rates) 292 u32 supp_rates, bool auth)
315 __acquires(RCU) 293 __acquires(RCU)
316{ 294{
317 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 295 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
@@ -353,7 +331,42 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
353 sta->sta.supp_rates[band] = supp_rates | 331 sta->sta.supp_rates[band] = supp_rates |
354 ieee80211_mandatory_rates(local, band); 332 ieee80211_mandatory_rates(local, band);
355 333
356 return ieee80211_ibss_finish_sta(sta); 334 return ieee80211_ibss_finish_sta(sta, auth);
335}
336
337static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
338 struct ieee80211_mgmt *mgmt,
339 size_t len)
340{
341 u16 auth_alg, auth_transaction;
342
343 lockdep_assert_held(&sdata->u.ibss.mtx);
344
345 if (len < 24 + 6)
346 return;
347
348 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
349 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
350
351 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
352 return;
353#ifdef CONFIG_MAC80211_IBSS_DEBUG
354 printk(KERN_DEBUG "%s: RX Auth SA=%pM DA=%pM BSSID=%pM."
355 "(auth_transaction=%d)\n",
356 sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction);
357#endif
358 sta_info_destroy_addr(sdata, mgmt->sa);
359 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
360 rcu_read_unlock();
361
362 /*
363 * IEEE 802.11 standard does not require authentication in IBSS
364 * networks and most implementations do not seem to use it.
365 * However, try to reply to authentication attempts if someone
366 * has actually implemented this.
367 */
368 ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
369 mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0);
357} 370}
358 371
359static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 372static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -418,7 +431,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
418 } else { 431 } else {
419 rcu_read_unlock(); 432 rcu_read_unlock();
420 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, 433 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
421 mgmt->sa, supp_rates); 434 mgmt->sa, supp_rates, true);
422 } 435 }
423 } 436 }
424 437
@@ -546,7 +559,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
546 ieee80211_sta_join_ibss(sdata, bss); 559 ieee80211_sta_join_ibss(sdata, bss);
547 supp_rates = ieee80211_sta_get_rates(local, elems, band); 560 supp_rates = ieee80211_sta_get_rates(local, elems, band);
548 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 561 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
549 supp_rates); 562 supp_rates, true);
550 rcu_read_unlock(); 563 rcu_read_unlock();
551 } 564 }
552 565
@@ -947,7 +960,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
947 list_del(&sta->list); 960 list_del(&sta->list);
948 spin_unlock_bh(&ifibss->incomplete_lock); 961 spin_unlock_bh(&ifibss->incomplete_lock);
949 962
950 ieee80211_ibss_finish_sta(sta); 963 ieee80211_ibss_finish_sta(sta, true);
951 rcu_read_unlock(); 964 rcu_read_unlock();
952 spin_lock_bh(&ifibss->incomplete_lock); 965 spin_lock_bh(&ifibss->incomplete_lock);
953 } 966 }