Patchwork [1/3] hostapd: Allow mlme frames to be sent without expecting an ACK

login
register
mail settings
Submitter Helmut Schaa
Date Nov. 10, 2011, 3:21 p.m.
Message ID <1320938481-23936-1-git-send-email-helmut.schaa@googlemail.com>
Download mbox | patch
Permalink /patch/124903/
State Accepted
Commit 8cfa3527e174f93e6d14b0cf1197fd02cb9e2ded
Headers show

Comments

Helmut Schaa - Nov. 10, 2011, 3:21 p.m.
In some situations it might be benefical to send a unicast frame without
the need for getting it ACKed (probe responses for example). In order to
achieve this add a new noack parameter to the drivers send_mlme callback
that can be used to advise the driver to not wait for an ACK for this
frame.

Signed-hostap: Helmut Schaa <helmut.schaa@googlemail.com>
---
 hostapd/ctrl_iface.c         |    2 +-
 src/ap/ap_drv_ops.c          |    4 ++--
 src/ap/ap_drv_ops.h          |    2 +-
 src/ap/beacon.c              |    2 +-
 src/ap/ieee802_11.c          |    8 ++++----
 src/ap/wmm.c                 |    2 +-
 src/drivers/driver.h         |    3 ++-
 src/drivers/driver_bsd.c     |    3 ++-
 src/drivers/driver_hostap.c  |   10 +++++-----
 src/drivers/driver_nl80211.c |   10 +++++-----
 src/drivers/driver_test.c    |    2 +-
 wpa_supplicant/driver_i.h    |    2 +-
 12 files changed, 26 insertions(+), 24 deletions(-)
Jouni Malinen - Nov. 19, 2011, 5:34 p.m.
On Thu, Nov 10, 2011 at 04:21:19PM +0100, Helmut Schaa wrote:
> In some situations it might be benefical to send a unicast frame without
> the need for getting it ACKed (probe responses for example). In order to
> achieve this add a new noack parameter to the drivers send_mlme callback
> that can be used to advise the driver to not wait for an ACK for this
> frame.

Thanks, applied. Though, I needed to fix number of cases where send_mlme
call had not been updated with the new argument and one case where an
incorrect function was modified with the new argument.

Patch

diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 4a6e011..7fb1e3e 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -567,7 +567,7 @@  static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
 	os_memcpy(pos, url, url_len);
 	pos += url_len;
 
-	if (hostapd_drv_send_mlme(hapd, buf, pos - buf) < 0) {
+	if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) {
 		wpa_printf(MSG_DEBUG, "Failed to send BSS Transition "
 			   "Management Request frame");
 		return -1;
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 733c917..0a0521f 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -573,11 +573,11 @@  int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
 
 
 int hostapd_drv_send_mlme(struct hostapd_data *hapd,
-			  const void *msg, size_t len)
+			  const void *msg, size_t len, int noack)
 {
 	if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
 		return 0;
-	return hapd->driver->send_mlme(hapd->drv_priv, msg, len);
+	return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack);
 }
 
 
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 66e2cb8..c918a4a 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -89,7 +89,7 @@  int hostapd_drv_set_key(const char *ifname,
 			const u8 *seq, size_t seq_len,
 			const u8 *key, size_t key_len);
 int hostapd_drv_send_mlme(struct hostapd_data *hapd,
-			  const void *msg, size_t len);
+			  const void *msg, size_t len, int noack);
 int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
 			   const u8 *addr, int reason);
 int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 4ba223c..6267831 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -407,7 +407,7 @@  void handle_probe_req(struct hostapd_data *hapd,
 		pos = hostapd_eid_p2p_manage(hapd, pos);
 #endif /* CONFIG_P2P_MANAGER */
 
-	if (hostapd_drv_send_mlme(hapd, resp, pos - (u8 *) resp) < 0)
+	if (hostapd_drv_send_mlme(hapd, resp, pos - (u8 *) resp, 0) < 0)
 		perror("handle_probe_req: send");
 
 	os_free(resp);
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 128faa7..888ff6b 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -269,7 +269,7 @@  static void send_auth_reply(struct hostapd_data *hapd,
 		   " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
 		   MAC2STR(dst), auth_alg, auth_transaction,
 		   resp, (unsigned long) ies_len);
-	if (hostapd_drv_send_mlme(hapd, reply, rlen) < 0)
+	if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0)
 		perror("send_auth_reply: send");
 
 	os_free(buf);
@@ -807,7 +807,7 @@  static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
 	send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
 	reply.u.deauth.reason_code = host_to_le16(reason_code);
 
-	if (hostapd_drv_send_mlme(hapd, &reply, send_len) < 0)
+	if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0)
 		wpa_printf(MSG_INFO, "Failed to send deauth: %s",
 			   strerror(errno));
 }
@@ -912,7 +912,7 @@  static void send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
 
 	send_len += p - reply->u.assoc_resp.variable;
 
-	if (hostapd_drv_send_mlme(hapd, reply, send_len) < 0)
+	if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0)
 		wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
 			   strerror(errno));
 }
@@ -1326,7 +1326,7 @@  static void handle_action(struct hostapd_data *hapd,
 		os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
 		resp->u.action.category |= 0x80;
 
-		hostapd_drv_send_mlme(hapd, resp, len);
+		hostapd_drv_send_mlme(hapd, resp, len, 0);
 		os_free(resp);
 	}
 }
diff --git a/src/ap/wmm.c b/src/ap/wmm.c
index a6d9b89..d6d8a10 100644
--- a/src/ap/wmm.c
+++ b/src/ap/wmm.c
@@ -153,7 +153,7 @@  static void wmm_send_action(struct hostapd_data *hapd, const u8 *addr,
 	os_memcpy(t, tspec, sizeof(struct wmm_tspec_element));
 	len = ((u8 *) (t + 1)) - buf;
 
-	if (hostapd_drv_send_mlme(hapd, m, len) < 0)
+	if (hostapd_drv_send_mlme(hapd, m, len, 0) < 0)
 		perror("wmm_send_action: send");
 }
 
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 06f2db3..e54870f 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1276,9 +1276,10 @@  struct wpa_driver_ops {
 	 * @priv: Private driver interface data
 	 * @data: IEEE 802.11 management frame with IEEE 802.11 header
 	 * @data_len: Size of the management frame
+	 * @noack: Don't wait for this frame to be acked
 	 * Returns: 0 on success, -1 on failure
 	 */
-	int (*send_mlme)(void *priv, const u8 *data, size_t data_len);
+	int (*send_mlme)(void *priv, const u8 *data, size_t data_len, int noack);
 
 	/**
 	 * update_ft_ies - Update FT (IEEE 802.11r) IEs
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index 4596a51..1dd407a 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -246,7 +246,8 @@  bsd_del_key(void *priv, const u8 *addr, int key_idx)
 }
 
 static int
-bsd_send_mlme_param(void *priv, const u8 op, const u16 reason, const u8 *addr)
+bsd_send_mlme_param(void *priv, const u8 op, const u16 reason, const u8 *addr,
+		    int noack)
 {
 	struct ieee80211req_mlme mlme;
 
diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c
index 85e9251..ba9ba2d 100644
--- a/src/drivers/driver_hostap.c
+++ b/src/drivers/driver_hostap.c
@@ -272,7 +272,7 @@  static int hostap_init_sockets(struct hostap_driver_data *drv, u8 *own_addr)
 }
 
 
-static int hostap_send_mlme(void *priv, const u8 *msg, size_t len)
+static int hostap_send_mlme(void *priv, const u8 *msg, size_t len, int noack)
 {
 	struct hostap_driver_data *drv = priv;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) msg;
@@ -321,7 +321,7 @@  static int hostap_send_eapol(void *priv, const u8 *addr, const u8 *data,
 	pos += 2;
 	memcpy(pos, data, data_len);
 
-	res = hostap_send_mlme(drv, (u8 *) hdr, len);
+	res = hostap_send_mlme(drv, (u8 *) hdr, len, 0);
 	if (res < 0) {
 		wpa_printf(MSG_ERROR, "hostap_send_eapol - packet len: %lu - "
 			   "failed: %d (%s)",
@@ -1053,7 +1053,7 @@  static int hostap_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
 	memcpy(mgmt.bssid, own_addr, ETH_ALEN);
 	mgmt.u.deauth.reason_code = host_to_le16(reason);
 	return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN +
-				sizeof(mgmt.u.deauth));
+				sizeof(mgmt.u.deauth), 0);
 }
 
 
@@ -1090,7 +1090,7 @@  static int hostap_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
 	memcpy(mgmt.bssid, own_addr, ETH_ALEN);
 	mgmt.u.disassoc.reason_code = host_to_le16(reason);
 	return  hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN +
-				 sizeof(mgmt.u.disassoc));
+				 sizeof(mgmt.u.disassoc), 0);
 }
 
 
@@ -1168,7 +1168,7 @@  static void wpa_driver_hostap_poll_client(void *priv, const u8 *own_addr,
 	os_memcpy(hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
 	os_memcpy(hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
 
-	hostap_send_mlme(priv, (u8 *)&hdr, sizeof(hdr));
+	hostap_send_mlme(priv, (u8 *)&hdr, sizeof(hdr), 0);
 }
 
 #else /* HOSTAPD */
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 2ab10ae..4c806c5 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -4203,7 +4203,7 @@  static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv,
 
 
 static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
-					size_t data_len)
+					size_t data_len, int noack)
 {
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -6304,7 +6304,7 @@  static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
 	mgmt.u.deauth.reason_code = host_to_le16(reason);
 	return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
 					    IEEE80211_HDRLEN +
-					    sizeof(mgmt.u.deauth));
+					    sizeof(mgmt.u.deauth), 0);
 }
 
 
@@ -6323,7 +6323,7 @@  static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
 	mgmt.u.disassoc.reason_code = host_to_le16(reason);
 	return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
 					    IEEE80211_HDRLEN +
-					    sizeof(mgmt.u.disassoc));
+					    sizeof(mgmt.u.disassoc), 0);
 }
 
 #endif /* HOSTAPD || CONFIG_AP */
@@ -6905,7 +6905,7 @@  static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
 	os_memcpy(hdr->addr3, bssid, ETH_ALEN);
 
 	if (is_ap_interface(drv->nlmode))
-		ret = wpa_driver_nl80211_send_mlme(priv, buf, 24 + data_len);
+		ret = wpa_driver_nl80211_send_mlme(priv, buf, 24 + data_len, 0);
 	else
 		ret = nl80211_send_frame_cmd(drv, freq, wait_time, buf,
 					     24 + data_len,
@@ -7454,7 +7454,7 @@  static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
 	os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
 	os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
 
-	if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size) < 0)
+	if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0) < 0)
 		wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
 			   "send poll frame");
 }
diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c
index 4b3d00f..bbac324 100644
--- a/src/drivers/driver_test.c
+++ b/src/drivers/driver_test.c
@@ -309,7 +309,7 @@  static int test_driver_send_ether(void *priv, const u8 *dst, const u8 *src,
 
 
 static int wpa_driver_test_send_mlme(void *priv, const u8 *data,
-				     size_t data_len)
+				     size_t data_len, int noack)
 {
 	struct test_driver_bss *dbss = priv;
 	struct wpa_driver_test_data *drv = dbss->drv;
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index b18f3fc..847bf80 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -266,7 +266,7 @@  static inline int wpa_drv_send_mlme(struct wpa_supplicant *wpa_s,
 {
 	if (wpa_s->driver->send_mlme)
 		return wpa_s->driver->send_mlme(wpa_s->drv_priv,
-						data, data_len);
+						data, data_len, 0);
 	return -1;
 }