From: Johannes Berg <johannes@sipsolutions.net>
To: linux-wireless@vger.kernel.org
Subject: [RFC v2 07/12] mac80211: support client probe
Date: Fri, 21 Oct 2011 16:23:29 +0200 [thread overview]
Message-ID: <20111021142429.002962879@sipsolutions.net> (raw)
In-Reply-To: 20111021142322.229128720@sipsolutions.net
From: Johannes Berg <johannes.berg@intel.com>
Support probing clients with null data frames
in AP mode.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
v2: update to use cfg80211_probe_status
net/mac80211/cfg.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++
net/mac80211/status.c | 45 +++++++++++++++++++--------------
2 files changed, 95 insertions(+), 18 deletions(-)
--- a/net/mac80211/cfg.c 2011-10-21 12:07:38.000000000 +0200
+++ b/net/mac80211/cfg.c 2011-10-21 12:07:42.000000000 +0200
@@ -2507,6 +2507,73 @@ static int ieee80211_tdls_oper(struct wi
return 0;
}
+static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *peer, u64 *cookie)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_qos_hdr *nullfunc;
+ struct sk_buff *skb;
+ int size = sizeof(*nullfunc);
+ __le16 fc;
+ bool qos;
+ struct ieee80211_tx_info *info;
+ struct sta_info *sta;
+
+ rcu_read_lock();
+ sta = sta_info_get(sdata, peer);
+ if (sta)
+ qos = test_sta_flag(sta, WLAN_STA_WME);
+ rcu_read_unlock();
+
+ if (!sta)
+ return -ENOLINK;
+
+ if (qos) {
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_QOS_NULLFUNC |
+ IEEE80211_FCTL_FROMDS);
+ } else {
+ size -= 2;
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_NULLFUNC |
+ IEEE80211_FCTL_FROMDS);
+ }
+
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + size);
+ if (!skb)
+ return -ENOMEM;
+
+ skb->dev = dev;
+
+ skb_reserve(skb, local->hw.extra_tx_headroom);
+
+ nullfunc = (void *) skb_put(skb, size);
+ nullfunc->frame_control = fc;
+ nullfunc->duration_id = 0;
+ memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN);
+ memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
+ memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN);
+ nullfunc->seq_ctrl = 0;
+
+ info = IEEE80211_SKB_CB(skb);
+
+ info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
+ IEEE80211_TX_INTFL_NL80211_FRAME_TX;
+
+ skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+ skb->priority = 7;
+ if (qos)
+ nullfunc->qos_ctrl = cpu_to_le16(7);
+
+ local_bh_disable();
+ ieee80211_xmit(sdata, skb);
+ local_bh_enable();
+
+ *cookie = (unsigned long) skb;
+ return 0;
+}
+
struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -2572,4 +2639,5 @@ struct cfg80211_ops mac80211_config_ops
.set_rekey_data = ieee80211_set_rekey_data,
.tdls_oper = ieee80211_tdls_oper,
.tdls_mgmt = ieee80211_tdls_mgmt,
+ .probe_client = ieee80211_probe_client,
};
--- a/net/mac80211/status.c 2011-10-21 12:07:38.000000000 +0200
+++ b/net/mac80211/status.c 2011-10-21 12:07:42.000000000 +0200
@@ -516,27 +516,36 @@ void ieee80211_tx_status(struct ieee8021
}
if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {
- struct ieee80211_work *wk;
u64 cookie = (unsigned long)skb;
- rcu_read_lock();
- list_for_each_entry_rcu(wk, &local->work_list, list) {
- if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
- continue;
- if (wk->offchan_tx.frame != skb)
- continue;
- wk->offchan_tx.status = true;
- break;
- }
- rcu_read_unlock();
- if (local->hw_roc_skb_for_status == skb) {
- cookie = local->hw_roc_cookie ^ 2;
- local->hw_roc_skb_for_status = NULL;
- }
+ if (ieee80211_is_nullfunc(hdr->frame_control) ||
+ ieee80211_is_qos_nullfunc(hdr->frame_control)) {
+ bool acked = info->flags & IEEE80211_TX_STAT_ACK;
+ cfg80211_probe_status(skb->dev, hdr->addr1,
+ cookie, acked, GFP_ATOMIC);
+ } else {
+ struct ieee80211_work *wk;
- cfg80211_mgmt_tx_status(
- skb->dev, cookie, skb->data, skb->len,
- !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);
+ rcu_read_lock();
+ list_for_each_entry_rcu(wk, &local->work_list, list) {
+ if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)
+ continue;
+ if (wk->offchan_tx.frame != skb)
+ continue;
+ wk->offchan_tx.status = true;
+ break;
+ }
+ rcu_read_unlock();
+ if (local->hw_roc_skb_for_status == skb) {
+ cookie = local->hw_roc_cookie ^ 2;
+ local->hw_roc_skb_for_status = NULL;
+ }
+
+ cfg80211_mgmt_tx_status(
+ skb->dev, cookie, skb->data, skb->len,
+ !!(info->flags & IEEE80211_TX_STAT_ACK),
+ GFP_ATOMIC);
+ }
}
/* this was a transmitted frame, but now we want to reuse it */
next prev parent reply other threads:[~2011-10-21 14:25 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-21 14:23 [RFC v2 00/12] get rid of AP mode monitor interfaces Johannes Berg
2011-10-21 14:23 ` [RFC v2 01/12] mac80211: add helper to free TX skb Johannes Berg
2011-10-21 14:23 ` [RFC v2 02/12] mac80211: add support for control port protocol in AP mode Johannes Berg
2011-10-21 14:23 ` [RFC v2 03/12] nl80211: allow subscribing to unexpected class3 frames Johannes Berg
2011-10-21 14:23 ` [RFC v2 04/12] mac80211: support spurious class3 event Johannes Berg
2011-10-21 14:23 ` [RFC v2 05/12] nl80211: advertise device AP SME Johannes Berg
2011-10-25 10:13 ` Eliad Peller
2011-10-21 14:23 ` [RFC v2 06/12] nl80211: add API to probe a client Johannes Berg
2011-10-21 14:23 ` Johannes Berg [this message]
2011-10-21 14:23 ` [RFC v2 08/12] net: add wireless TX status socket option Johannes Berg
2011-10-25 10:40 ` Eliad Peller
2011-10-21 14:23 ` [RFC v2 09/12] nl80211: advertise socket TX status capability Johannes Berg
2011-10-21 14:23 ` [RFC v2 10/12] mac80211: implement wifi TX status Johannes Berg
2011-10-21 14:23 ` [RFC v2 11/12] cfg80211: allow registering to beacons Johannes Berg
2011-10-21 14:23 ` [RFC v2 12/12] mac80211: report OBSS beacons Johannes Berg
2011-10-27 19:32 ` [RFC v2 13/12] cfg80211/mac80211: allow management TX to not wait for ACK Johannes Berg
2011-10-27 22:44 ` Eliad Peller
2011-10-28 8:02 ` Johannes Berg
2011-10-28 6:09 ` Helmut Schaa
2011-10-28 7:34 ` Johannes Berg
2011-10-28 7:48 ` Arend Van Spriel
2011-10-28 7:52 ` Helmut Schaa
2011-10-28 9:07 ` Arend Van Spriel
2011-10-28 9:15 ` Johannes Berg
2011-10-28 8:01 ` Johannes Berg
2011-10-28 9:10 ` Arend Van Spriel
2011-10-28 9:28 ` Helmut Schaa
2011-10-28 13:34 ` Kalle Valo
2011-10-29 12:01 ` Helmut Schaa
2011-10-28 17:22 ` Arend van Spriel
2011-10-28 9:18 ` [RFC v3 " Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20111021142429.002962879@sipsolutions.net \
--to=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).