aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-11-10 04:28:57 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-11 12:32:51 -0500
commit029458212604570eec4789049a8a74428484dbb4 (patch)
treecabbe65d50e83498300a25b02a67f8475c02c3b7 /net
parent00f740e1a3b7abb51980371ee8fa113df22ae0b8 (diff)
mac80211: Save probe response data for bss
Allow setting a probe response template for an interface operating in AP mode. Low level drivers are notified about changes in the probe response template and are able to retrieve a copy of the current probe response. This data can, for example, be uploaded to hardware as a template. Signed-off-by: Guy Eilam <guy@wizery.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c38
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/mac80211/tx.c31
-rw-r--r--net/mac80211/util.c3
5 files changed, 74 insertions, 5 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 192f213cf43e..c2416fbd1b27 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -491,6 +491,31 @@ static void ieee80211_config_ap_ssid(struct ieee80211_sub_if_data *sdata,
491 (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); 491 (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
492} 492}
493 493
494static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
495 u8 *resp, size_t resp_len)
496{
497 struct sk_buff *new, *old;
498
499 if (!resp || !resp_len)
500 return -EINVAL;
501
502 old = sdata->u.ap.probe_resp;
503
504 new = dev_alloc_skb(resp_len);
505 if (!new)
506 return -ENOMEM;
507
508 memcpy(skb_put(new, resp_len), resp, resp_len);
509
510 rcu_assign_pointer(sdata->u.ap.probe_resp, new);
511 synchronize_rcu();
512
513 if (old)
514 dev_kfree_skb(old);
515
516 return 0;
517}
518
494/* 519/*
495 * This handles both adding a beacon and setting new beacon info 520 * This handles both adding a beacon and setting new beacon info
496 */ 521 */
@@ -501,6 +526,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
501 int new_head_len, new_tail_len; 526 int new_head_len, new_tail_len;
502 int size; 527 int size;
503 int err = -EINVAL; 528 int err = -EINVAL;
529 u32 changed = 0;
504 530
505 old = rtnl_dereference(sdata->u.ap.beacon); 531 old = rtnl_dereference(sdata->u.ap.beacon);
506 532
@@ -584,11 +610,17 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
584 610
585 kfree(old); 611 kfree(old);
586 612
613 err = ieee80211_set_probe_resp(sdata, params->probe_resp,
614 params->probe_resp_len);
615 if (!err)
616 changed |= BSS_CHANGED_AP_PROBE_RESP;
617
587 ieee80211_config_ap_ssid(sdata, params); 618 ieee80211_config_ap_ssid(sdata, params);
619 changed |= BSS_CHANGED_BEACON_ENABLED |
620 BSS_CHANGED_BEACON |
621 BSS_CHANGED_SSID;
588 622
589 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | 623 ieee80211_bss_info_change_notify(sdata, changed);
590 BSS_CHANGED_BEACON |
591 BSS_CHANGED_SSID);
592 return 0; 624 return 0;
593} 625}
594 626
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 873d681a8e52..068cc92d16aa 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -232,6 +232,7 @@ struct beacon_data {
232 232
233struct ieee80211_if_ap { 233struct ieee80211_if_ap {
234 struct beacon_data __rcu *beacon; 234 struct beacon_data __rcu *beacon;
235 struct sk_buff __rcu *probe_resp;
235 236
236 struct list_head vlans; 237 struct list_head vlans;
237 238
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7b0c25bf8bbf..12a6d4bb5d37 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -462,15 +462,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
462 struct ieee80211_sub_if_data *vlan, *tmpsdata; 462 struct ieee80211_sub_if_data *vlan, *tmpsdata;
463 struct beacon_data *old_beacon = 463 struct beacon_data *old_beacon =
464 rtnl_dereference(sdata->u.ap.beacon); 464 rtnl_dereference(sdata->u.ap.beacon);
465 struct sk_buff *old_probe_resp =
466 rtnl_dereference(sdata->u.ap.probe_resp);
465 467
466 /* sdata_running will return false, so this will disable */ 468 /* sdata_running will return false, so this will disable */
467 ieee80211_bss_info_change_notify(sdata, 469 ieee80211_bss_info_change_notify(sdata,
468 BSS_CHANGED_BEACON_ENABLED); 470 BSS_CHANGED_BEACON_ENABLED);
469 471
470 /* remove beacon */ 472 /* remove beacon and probe response */
471 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); 473 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
474 RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
472 synchronize_rcu(); 475 synchronize_rcu();
473 kfree(old_beacon); 476 kfree(old_beacon);
477 kfree(old_probe_resp);
474 478
475 /* down all dependent devices, that is VLANs */ 479 /* down all dependent devices, that is VLANs */
476 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, 480 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ab6cb56bc74d..2b413d38daa7 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2415,6 +2415,37 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2415} 2415}
2416EXPORT_SYMBOL(ieee80211_beacon_get_tim); 2416EXPORT_SYMBOL(ieee80211_beacon_get_tim);
2417 2417
2418struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
2419 struct ieee80211_vif *vif)
2420{
2421 struct ieee80211_if_ap *ap = NULL;
2422 struct sk_buff *presp = NULL, *skb = NULL;
2423 struct ieee80211_hdr *hdr;
2424 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
2425
2426 if (sdata->vif.type != NL80211_IFTYPE_AP)
2427 return NULL;
2428
2429 rcu_read_lock();
2430
2431 ap = &sdata->u.ap;
2432 presp = rcu_dereference(ap->probe_resp);
2433 if (!presp)
2434 goto out;
2435
2436 skb = skb_copy(presp, GFP_ATOMIC);
2437 if (!skb)
2438 goto out;
2439
2440 hdr = (struct ieee80211_hdr *) skb->data;
2441 memset(hdr->addr1, 0, sizeof(hdr->addr1));
2442
2443out:
2444 rcu_read_unlock();
2445 return skb;
2446}
2447EXPORT_SYMBOL(ieee80211_proberesp_get);
2448
2418struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, 2449struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
2419 struct ieee80211_vif *vif) 2450 struct ieee80211_vif *vif)
2420{ 2451{
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 6ed0aa430789..4cf25b0eea74 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1071,7 +1071,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1071 changed |= BSS_CHANGED_IBSS; 1071 changed |= BSS_CHANGED_IBSS;
1072 /* fall through */ 1072 /* fall through */
1073 case NL80211_IFTYPE_AP: 1073 case NL80211_IFTYPE_AP:
1074 changed |= BSS_CHANGED_SSID; 1074 changed |= BSS_CHANGED_SSID |
1075 BSS_CHANGED_AP_PROBE_RESP;
1075 /* fall through */ 1076 /* fall through */
1076 case NL80211_IFTYPE_MESH_POINT: 1077 case NL80211_IFTYPE_MESH_POINT:
1077 changed |= BSS_CHANGED_BEACON | 1078 changed |= BSS_CHANGED_BEACON |