From patchwork Fri Nov 4 10:37:53 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 123589 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "maxx.shmoo.com", Issuer "CA Cert Signing Authority" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 23880B6F87 for ; Fri, 4 Nov 2011 21:40:41 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 40BD69D2E1; Fri, 4 Nov 2011 06:40:39 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kXOvn2Xa5VyT; Fri, 4 Nov 2011 06:40:39 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id A86189D2FC; Fri, 4 Nov 2011 06:39:49 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 38C149D2F5 for ; Fri, 4 Nov 2011 06:39:48 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KkkSevldsWJa for ; Fri, 4 Nov 2011 06:39:43 -0400 (EDT) Received: from sipsolutions.net (he.sipsolutions.net [78.46.109.217]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id 746E79D2E0 for ; Fri, 4 Nov 2011 06:39:18 -0400 (EDT) Received: by sipsolutions.net with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.77) (envelope-from ) id 1RMHB7-0001Gc-Em for hostap@lists.shmoo.com; Fri, 04 Nov 2011 11:39:17 +0100 Message-Id: <20111104103809.115615960@sipsolutions.net> User-Agent: quilt/0.48-1 Date: Fri, 04 Nov 2011 11:37:53 +0100 From: Johannes Berg To: hostap@lists.shmoo.com Subject: [PATCH 04/18] driver_nl80211: support in-kernel station poll References: <20111104103749.617144560@sipsolutions.net> Content-Disposition: inline; filename=0004-driver_nl80211-support-in-kernel-station-poll.patch Mime-Version: 1.0 X-Mailer: Evolution 2.30.3 X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com From: Johannes Berg If the kernel supports this, don't use manual null data frame transmissions. This is one thing to get rid of cooked monitor interfaces. Signed-hostap: Johannes Berg --- src/drivers/driver_nl80211.c | 59 +++++++++++++++++++++++++++++++++++++++-- 1 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 51b65ba..1128e44 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -224,6 +224,7 @@ struct wpa_driver_nl80211_data { unsigned int pending_remain_on_chan:1; unsigned int in_interface_list:1; unsigned int device_ap_sme:1; + unsigned int poll_command_supported:1; u64 remain_on_chan_cookie; u64 send_action_cookie; @@ -1688,6 +1689,22 @@ static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv, } +static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv, + struct nlattr **tb) +{ + union wpa_event_data data; + + if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_ACK]) + return; + + os_memset(&data, 0, sizeof(data)); + os_memcpy(data.client_poll.addr, + nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN); + + wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data); +} + + static int process_event(struct nl_msg *msg, void *arg) { struct wpa_driver_nl80211_data *drv = arg; @@ -1810,6 +1827,9 @@ static int process_event(struct nl_msg *msg, void *arg) case NL80211_CMD_PMKSA_CANDIDATE: nl80211_pmksa_candidate_event(drv, tb); break; + case NL80211_CMD_PROBE_CLIENT: + nl80211_client_probe_event(drv, tb); + break; default: wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event " "(cmd=%d)", gnlh->cmd); @@ -1878,6 +1898,7 @@ struct wiphy_info_data { unsigned int error:1; unsigned int device_ap_sme:1; + unsigned int poll_command_supported:1; }; @@ -2009,6 +2030,9 @@ broken_combination: case NL80211_CMD_START_SCHED_SCAN: capa->sched_scan_supported = 1; break; + case NL80211_CMD_PROBE_CLIENT: + info->poll_command_supported = 1; + break; } } } @@ -2120,6 +2144,7 @@ static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv) drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS; drv->device_ap_sme = info.device_ap_sme; + drv->poll_command_supported = info.poll_command_supported; return 0; } @@ -7432,10 +7457,11 @@ static void nl80211_set_rekey_info(void *priv, const u8 *kek, const u8 *kck, } -static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr, - int qos) +static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr, + const u8 *addr, int qos) { - struct i802_bss *bss = priv; + /* send data frame to poll STA and check whether + * this frame is ACKed */ struct { struct ieee80211_hdr hdr; u16 qos_ctl; @@ -7468,6 +7494,33 @@ static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr, "send poll frame"); } +static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr, + int qos) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + + if (!drv->poll_command_supported) { + nl80211_send_null_frame(bss, own_addr, addr, qos); + return; + } + + msg = nlmsg_alloc(); + if (!msg) + return; + + nl80211_cmd(drv, msg, 0, NL80211_CMD_PROBE_CLIENT); + + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex); + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); + + send_and_recv_msgs(drv, msg, NULL, NULL); + return; + nla_put_failure: + nlmsg_free(msg); +} + #ifdef CONFIG_TDLS