Allow MLME frames to be sent without expecting an ACK (no retries)
authorHelmut Schaa <helmut.schaa@googlemail.com>
Sat, 19 Nov 2011 17:02:05 +0000 (19:02 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 19 Nov 2011 17:02:05 +0000 (19:02 +0200)
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>

13 files changed:
hostapd/ctrl_iface.c
src/ap/ap_drv_ops.c
src/ap/ap_drv_ops.h
src/ap/beacon.c
src/ap/ieee802_11.c
src/ap/ieee802_11_shared.c
src/ap/wmm.c
src/ap/wpa_auth_glue.c
src/drivers/driver.h
src/drivers/driver_hostap.c
src/drivers/driver_nl80211.c
src/drivers/driver_test.c
wpa_supplicant/driver_i.h

index 61bd1e5..8284ab6 100644 (file)
@@ -566,7 +566,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;
index 01c28b9..77d647b 100644 (file)
@@ -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);
 }
 
 
index 66e2cb8..c918a4a 100644 (file)
@@ -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,
index 4ba223c..6267831 100644 (file)
@@ -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);
index e1d8169..36f04d5 100644 (file)
@@ -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);
@@ -805,7 +805,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));
 }
@@ -910,7 +910,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));
 }
@@ -1322,7 +1322,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);
        }
 }
index 52a4572..8503fce 100644 (file)
@@ -74,7 +74,7 @@ void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
        os_memcpy(mgmt.u.action.u.sa_query_req.trans_id, trans_id,
                  WLAN_SA_QUERY_TR_ID_LEN);
        end = mgmt.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
-       if (hostapd_drv_send_mlme(hapd, &mgmt, end - (u8 *) &mgmt) < 0)
+       if (hostapd_drv_send_mlme(hapd, &mgmt, end - (u8 *) &mgmt, 0) < 0)
                perror("ieee802_11_send_sa_query_req: send");
 }
 
@@ -112,7 +112,7 @@ static void ieee802_11_send_sa_query_resp(struct hostapd_data *hapd,
        os_memcpy(resp.u.action.u.sa_query_req.trans_id, trans_id,
                  WLAN_SA_QUERY_TR_ID_LEN);
        end = resp.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
-       if (hostapd_drv_send_mlme(hapd, &resp, end - (u8 *) &resp) < 0)
+       if (hostapd_drv_send_mlme(hapd, &resp, end - (u8 *) &resp, 0) < 0)
                perror("ieee80211_mgmt_sa_query_request: send");
 }
 
index a6d9b89..d6d8a10 100644 (file)
@@ -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");
 }
 
index fc58f9d..1e9d422 100644 (file)
@@ -416,7 +416,7 @@ static int hostapd_wpa_auth_send_ft_action(void *ctx, const u8 *dst,
        os_memcpy(m->bssid, hapd->own_addr, ETH_ALEN);
        os_memcpy(&m->u, data, data_len);
 
-       res = hostapd_drv_send_mlme(hapd, (u8 *) m, mlen);
+       res = hostapd_drv_send_mlme(hapd, (u8 *) m, mlen, 0);
        os_free(m);
        return res;
 }
index dbf3c6e..ce25d03 100644 (file)
@@ -1276,9 +1276,11 @@ 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: Do not wait for this frame to be acked (disable retries)
         * 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
index 454613a..8fc0efd 100644 (file)
@@ -270,7 +270,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;
@@ -319,7 +319,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)",
@@ -1051,7 +1051,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);
 }
 
 
@@ -1088,7 +1088,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);
 }
 
 
@@ -1166,7 +1166,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);
 }
 
 
index f42011a..4884d62 100644 (file)
@@ -4209,7 +4209,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;
@@ -6328,7 +6328,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);
 }
 
 
@@ -6347,7 +6347,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 */
@@ -6929,7 +6929,8 @@ 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,
@@ -7515,7 +7516,7 @@ static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_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");
 }
index 4b3d00f..3faa85d 100644 (file)
@@ -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;
@@ -2705,7 +2705,7 @@ static int wpa_driver_test_send_action(void *priv, unsigned int freq,
        os_memcpy(hdr->addr2, src, ETH_ALEN);
        os_memcpy(hdr->addr3, bssid, ETH_ALEN);
 
-       ret = wpa_driver_test_send_mlme(priv, buf, 24 + data_len);
+       ret = wpa_driver_test_send_mlme(priv, buf, 24 + data_len, 0);
        os_free(buf);
        return ret;
 }
index b18f3fc..847bf80 100644 (file)
@@ -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;
 }