diff --git a/src/drivers/driver.h b/src/drivers/driver.h index a41d890af..4a9be3567 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1862,6 +1862,7 @@ struct wpa_driver_ops { * @bssid: BSSID (Address 3) * @data: Frame body * @data_len: data length in octets + @ @no_cck: Whether CCK rates must not be used to transmit this frame * Returns: 0 on success, -1 on failure * * This command can be used to request the driver to transmit an action @@ -1879,7 +1880,7 @@ struct wpa_driver_ops { */ int (*send_action)(void *priv, unsigned int freq, unsigned int wait, const u8 *dst, const u8 *src, const u8 *bssid, - const u8 *data, size_t data_len); + const u8 *data, size_t data_len, int no_cck); /** * send_action_cancel_wait - Cancel action frame TX wait diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index de9d532d0..f22e847d5 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -266,7 +266,8 @@ static void nl80211_remove_monitor_interface( struct wpa_driver_nl80211_data *drv); static int nl80211_send_frame_cmd(struct wpa_driver_nl80211_data *drv, unsigned int freq, unsigned int wait, - const u8 *buf, size_t buf_len, u64 *cookie); + const u8 *buf, size_t buf_len, u64 *cookie, + int no_cck); static int wpa_driver_nl80211_probe_req_report(void *priv, int report); #ifdef HOSTAPD @@ -4140,12 +4141,12 @@ static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data, * of wpa_supplicant. */ return nl80211_send_frame_cmd(drv, drv->last_mgmt_freq, 0, - data, data_len, NULL); + data, data_len, NULL, 1); } if (drv->no_monitor_iface_capab && is_ap_interface(drv->nlmode)) { return nl80211_send_frame_cmd(drv, drv->ap_oper_freq, 0, - data, data_len, NULL); + data, data_len, NULL, 0); } if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && @@ -6743,7 +6744,7 @@ static int cookie_handler(struct nl_msg *msg, void *arg) static int nl80211_send_frame_cmd(struct wpa_driver_nl80211_data *drv, unsigned int freq, unsigned int wait, const u8 *buf, size_t buf_len, - u64 *cookie_out) + u64 *cookie_out, int no_cck) { struct nl_msg *msg; u64 cookie; @@ -6760,7 +6761,8 @@ static int nl80211_send_frame_cmd(struct wpa_driver_nl80211_data *drv, if (wait) NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait); NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); - NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE); + if (no_cck) + NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE); NLA_PUT(msg, NL80211_ATTR_FRAME, buf_len, buf); @@ -6789,7 +6791,8 @@ static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq, unsigned int wait_time, const u8 *dst, const u8 *src, const u8 *bssid, - const u8 *data, size_t data_len) + const u8 *data, size_t data_len, + int no_cck) { struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; @@ -6798,7 +6801,7 @@ static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq, struct ieee80211_hdr *hdr; wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, " - "wait=%d ms)", drv->ifindex, wait_time); + "wait=%d ms no_cck=%d)", drv->ifindex, wait_time, no_cck); buf = os_zalloc(24 + data_len); if (buf == NULL) @@ -6816,7 +6819,8 @@ static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq, else ret = nl80211_send_frame_cmd(drv, freq, wait_time, buf, 24 + data_len, - &drv->send_action_cookie); + &drv->send_action_cookie, + no_cck); os_free(buf); return ret; @@ -7086,7 +7090,7 @@ static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap, ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, 0, drv->bssid, own_addr, drv->bssid, - data, data_len); + data, data_len, 0); os_free(data); return ret; diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index 3e8e7a6b6..4b3d00f4a 100644 --- a/src/drivers/driver_test.c +++ b/src/drivers/driver_test.c @@ -116,6 +116,7 @@ struct wpa_driver_test_data { u8 pending_action_dst[ETH_ALEN]; u8 pending_action_bssid[ETH_ALEN]; unsigned int pending_action_freq; + unsigned int pending_action_no_cck; unsigned int pending_listen_freq; unsigned int pending_listen_duration; int pending_p2p_scan; @@ -2670,7 +2671,8 @@ static int wpa_driver_test_send_action(void *priv, unsigned int freq, unsigned int wait, const u8 *dst, const u8 *src, const u8 *bssid, - const u8 *data, size_t data_len) + const u8 *data, size_t data_len, + int no_cck) { struct test_driver_bss *dbss = priv; struct wpa_driver_test_data *drv = dbss->drv; @@ -2730,7 +2732,8 @@ static void test_send_action_cb(void *eloop_ctx, void *timeout_ctx) drv->pending_action_src, drv->pending_action_bssid, wpabuf_head(drv->pending_action_tx), - wpabuf_len(drv->pending_action_tx)); + wpabuf_len(drv->pending_action_tx), + drv->pending_action_no_cck); } #endif /* CONFIG_P2P */ @@ -3013,6 +3016,7 @@ static int test_send_action(void *ctx, unsigned int freq, const u8 *dst, os_memcpy(drv->pending_action_dst, dst, ETH_ALEN); os_memcpy(drv->pending_action_bssid, bssid, ETH_ALEN); drv->pending_action_freq = freq; + drv->pending_action_no_cck = 1; if (drv->off_channel_freq == freq) { /* Already on requested channel; send immediately */ diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index b5f4393d5..0363f4dbf 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -352,12 +352,13 @@ static inline int wpa_drv_send_action(struct wpa_supplicant *wpa_s, unsigned int wait, const u8 *dst, const u8 *src, const u8 *bssid, - const u8 *data, size_t data_len) + const u8 *data, size_t data_len, + int no_cck) { if (wpa_s->driver->send_action) return wpa_s->driver->send_action(wpa_s->drv_priv, freq, wait, dst, src, bssid, - data, data_len); + data, data_len, no_cck); return -1; } diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c index 1ac185a23..3b736da2b 100644 --- a/wpa_supplicant/gas_query.c +++ b/wpa_supplicant/gas_query.c @@ -138,7 +138,7 @@ static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query, res = offchannel_send_action(gas->wpa_s, query->freq, query->addr, gas->wpa_s->own_addr, query->addr, wpabuf_head(req), wpabuf_len(req), 1000, - NULL); + NULL, 0); if (res == 0) query->offchannel_tx_started = 1; return res; diff --git a/wpa_supplicant/offchannel.c b/wpa_supplicant/offchannel.c index 8f8ef3a4d..790f14ae6 100644 --- a/wpa_supplicant/offchannel.c +++ b/wpa_supplicant/offchannel.c @@ -120,7 +120,8 @@ static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx) wpa_s->pending_action_src, wpa_s->pending_action_bssid, wpabuf_head(wpa_s->pending_action_tx), - wpabuf_len(wpa_s->pending_action_tx)); + wpabuf_len(wpa_s->pending_action_tx), + wpa_s->pending_action_no_cck); if (res) { wpa_printf(MSG_DEBUG, "Off-channel: Failed to send the " "pending Action frame"); @@ -177,7 +178,8 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq, const u8 *src, const u8 *bssid, const u8 *data, size_t data_len, enum offchannel_send_action_result - result)) + result), + int no_cck) { wpa_printf(MSG_DEBUG, "Off-channel: Send action frame: freq=%d dst=" MACSTR " src=" MACSTR " bssid=" MACSTR " len=%d", @@ -204,6 +206,7 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq, os_memcpy(wpa_s->pending_action_dst, dst, ETH_ALEN); os_memcpy(wpa_s->pending_action_bssid, bssid, ETH_ALEN); wpa_s->pending_action_freq = freq; + wpa_s->pending_action_no_cck = no_cck; if (freq != 0 && wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) { struct wpa_supplicant *iface; @@ -212,12 +215,13 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq, wpa_s->pending_action_src); wpa_s->action_tx_wait_time = wait_time; - return wpa_drv_send_action(iface, wpa_s->pending_action_freq, - wait_time, wpa_s->pending_action_dst, - wpa_s->pending_action_src, - wpa_s->pending_action_bssid, - wpabuf_head(wpa_s->pending_action_tx), - wpabuf_len(wpa_s->pending_action_tx)); + return wpa_drv_send_action( + iface, wpa_s->pending_action_freq, + wait_time, wpa_s->pending_action_dst, + wpa_s->pending_action_src, wpa_s->pending_action_bssid, + wpabuf_head(wpa_s->pending_action_tx), + wpabuf_len(wpa_s->pending_action_tx), + wpa_s->pending_action_no_cck); } if (freq) { diff --git a/wpa_supplicant/offchannel.h b/wpa_supplicant/offchannel.h index 90f79c145..60e0d0328 100644 --- a/wpa_supplicant/offchannel.h +++ b/wpa_supplicant/offchannel.h @@ -24,7 +24,8 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq, const u8 *src, const u8 *bssid, const u8 *data, size_t data_len, enum offchannel_send_action_result - result)); + result), + int no_cck); void offchannel_send_action_done(struct wpa_supplicant *wpa_s); void offchannel_remain_on_channel_cb(struct wpa_supplicant *wpa_s, unsigned int freq, unsigned int duration); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 929d2fd23..3eeb61ed6 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -593,7 +593,7 @@ static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst, struct wpa_supplicant *wpa_s = ctx; return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len, wait_time, - wpas_p2p_send_action_tx_status); + wpas_p2p_send_action_tx_status, 1); } diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index cba844454..da689d2ad 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -647,7 +647,7 @@ static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s, os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN); if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, wpa_s->own_addr, wpa_s->bssid, - req, sizeof(req)) < 0) + req, sizeof(req), 0) < 0) wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query " "Request"); } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index a11db03a8..3e6e5dd74 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -406,6 +406,7 @@ struct wpa_supplicant { u8 pending_action_dst[ETH_ALEN]; u8 pending_action_bssid[ETH_ALEN]; unsigned int pending_action_freq; + int pending_action_no_cck; int pending_action_without_roc; void (*pending_action_tx_status_cb)(struct wpa_supplicant *wpa_s, unsigned int freq, const u8 *dst,