aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/cfg.c16
-rw-r--r--net/mac80211/ieee80211_i.h8
-rw-r--r--net/mac80211/iface.c4
-rw-r--r--net/mac80211/tx.c7
4 files changed, 21 insertions, 14 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index df64b455821d..8052a7ad03a6 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -725,25 +725,23 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
725static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, 725static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
726 const u8 *resp, size_t resp_len) 726 const u8 *resp, size_t resp_len)
727{ 727{
728 struct sk_buff *new, *old; 728 struct probe_resp *new, *old;
729 729
730 if (!resp || !resp_len) 730 if (!resp || !resp_len)
731 return 1; 731 return -EINVAL;
732 732
733 old = rtnl_dereference(sdata->u.ap.probe_resp); 733 old = rtnl_dereference(sdata->u.ap.probe_resp);
734 734
735 new = dev_alloc_skb(resp_len); 735 new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL);
736 if (!new) 736 if (!new)
737 return -ENOMEM; 737 return -ENOMEM;
738 738
739 memcpy(skb_put(new, resp_len), resp, resp_len); 739 new->len = resp_len;
740 memcpy(new->data, resp, resp_len);
740 741
741 rcu_assign_pointer(sdata->u.ap.probe_resp, new); 742 rcu_assign_pointer(sdata->u.ap.probe_resp, new);
742 if (old) { 743 if (old)
743 /* TODO: use call_rcu() */ 744 kfree_rcu(old, rcu_head);
744 synchronize_rcu();
745 dev_kfree_skb(old);
746 }
747 745
748 return 0; 746 return 0;
749} 747}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d1a7c58a8c62..e22aee83ba53 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -272,9 +272,15 @@ struct beacon_data {
272 struct rcu_head rcu_head; 272 struct rcu_head rcu_head;
273}; 273};
274 274
275struct probe_resp {
276 struct rcu_head rcu_head;
277 int len;
278 u8 data[0];
279};
280
275struct ieee80211_if_ap { 281struct ieee80211_if_ap {
276 struct beacon_data __rcu *beacon; 282 struct beacon_data __rcu *beacon;
277 struct sk_buff __rcu *probe_resp; 283 struct probe_resp __rcu *probe_resp;
278 284
279 struct list_head vlans; 285 struct list_head vlans;
280 286
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index abee3a0c25ed..fbab7a84ca21 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -715,7 +715,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
715 struct ieee80211_sub_if_data *vlan, *tmpsdata; 715 struct ieee80211_sub_if_data *vlan, *tmpsdata;
716 struct beacon_data *old_beacon = 716 struct beacon_data *old_beacon =
717 rtnl_dereference(sdata->u.ap.beacon); 717 rtnl_dereference(sdata->u.ap.beacon);
718 struct sk_buff *old_probe_resp = 718 struct probe_resp *old_probe_resp =
719 rtnl_dereference(sdata->u.ap.probe_resp); 719 rtnl_dereference(sdata->u.ap.probe_resp);
720 720
721 /* sdata_running will return false, so this will disable */ 721 /* sdata_running will return false, so this will disable */
@@ -727,7 +727,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
727 RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL); 727 RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
728 synchronize_rcu(); 728 synchronize_rcu();
729 kfree(old_beacon); 729 kfree(old_beacon);
730 kfree_skb(old_probe_resp); 730 kfree(old_probe_resp);
731 731
732 /* down all dependent devices, that is VLANs */ 732 /* down all dependent devices, that is VLANs */
733 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, 733 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7dbcf293708b..2d004ba0615e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2481,7 +2481,8 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
2481 struct ieee80211_vif *vif) 2481 struct ieee80211_vif *vif)
2482{ 2482{
2483 struct ieee80211_if_ap *ap = NULL; 2483 struct ieee80211_if_ap *ap = NULL;
2484 struct sk_buff *presp = NULL, *skb = NULL; 2484 struct sk_buff *skb = NULL;
2485 struct probe_resp *presp = NULL;
2485 struct ieee80211_hdr *hdr; 2486 struct ieee80211_hdr *hdr;
2486 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 2487 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
2487 2488
@@ -2495,10 +2496,12 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
2495 if (!presp) 2496 if (!presp)
2496 goto out; 2497 goto out;
2497 2498
2498 skb = skb_copy(presp, GFP_ATOMIC); 2499 skb = dev_alloc_skb(presp->len);
2499 if (!skb) 2500 if (!skb)
2500 goto out; 2501 goto out;
2501 2502
2503 memcpy(skb_put(skb, presp->len), presp->data, presp->len);
2504
2502 hdr = (struct ieee80211_hdr *) skb->data; 2505 hdr = (struct ieee80211_hdr *) skb->data;
2503 memset(hdr->addr1, 0, sizeof(hdr->addr1)); 2506 memset(hdr->addr1, 0, sizeof(hdr->addr1));
2504 2507