In order to retransmit faster in AP mode, hostapd can handle tx status notifications. When using nl80211, this is currently only possible with socket control msgs. This patchs adds support for receiving such events directly over nl80211 and detecting, if this feature is supported. This finally allows for a clean separation between mgmt/ctrl path (over nl80211) and in-kernel data path. A follow up patch enables the feature in AP mode. Control port tx status contains the original frame content for matching with the current hostapd code. Furthermore, a cookie is included, which allows for matching against outstanding cookies in the future. This patch only prints the cookie value for debugging purposes on tx status receive. Signed-off-by: Markus Theil <markus.theil@xxxxxxxxxxxxx> --- src/drivers/driver.h | 4 +++- src/drivers/driver_nl80211_capa.c | 3 +++ src/drivers/driver_nl80211_event.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 350c1cb57..8d833537d 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1929,7 +1929,9 @@ struct wpa_driver_capa { u64 flags; /** Driver supports a separate control port RX for EAPOL frames */ -#define WPA_DRIVER_FLAGS2_CONTROL_PORT_RX 0x0000000000000001ULL +#define WPA_DRIVER_FLAGS2_CONTROL_PORT_RX 0x0000000000000001ULL +/** Driver supports tx status reports for EAPOL frames */ +#define WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS 0x0000000000000002ULL u64 flags2; #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \ diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index 83a4481da..c6a663f56 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -621,6 +621,9 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info, if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH)) capa->flags2 |= WPA_DRIVER_FLAGS2_CONTROL_PORT_RX; + if (ext_feature_isset(ext_features, len, + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS)) + capa->flags2 |= WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS; if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_VLAN_OFFLOAD)) diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 6a2de1f3c..f7bf9d21e 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -138,6 +138,8 @@ static const char * nl80211_command_to_string(enum nl80211_commands cmd) C2S(NL80211_CMD_CONTROL_PORT_FRAME) C2S(NL80211_CMD_UPDATE_OWE_INFO) C2S(NL80211_CMD_UNPROT_BEACON) + C2S(NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS) + default: return "NL80211_CMD_UNKNOWN"; } @@ -2557,6 +2559,28 @@ static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv, } +static void nl80211_control_port_frame_tx_status(struct wpa_driver_nl80211_data *drv, + struct nlattr **tb) +{ + bool acked = tb[NL80211_ATTR_ACK]; + union wpa_event_data event; + + if (!tb[NL80211_ATTR_FRAME] || + !tb[NL80211_ATTR_COOKIE]) + return; + + if (nla_len(tb[NL80211_ATTR_FRAME]) < 14) + return; + + memset(&event, 0, sizeof(event)); + event.eapol_tx_status.dst = nla_data(tb[NL80211_ATTR_FRAME]); + event.eapol_tx_status.data = nla_data(tb[NL80211_ATTR_FRAME]) + 14; + event.eapol_tx_status.data_len = nla_len(tb[NL80211_ATTR_FRAME]) - 14; + event.eapol_tx_status.ack = acked; + wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event); +} + + static void do_process_drv_event(struct i802_bss *bss, int cmd, struct nlattr **tb) { @@ -2775,10 +2799,15 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, mlme_event_unprot_beacon(drv, nla_data(frame), nla_len(frame)); break; + case NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS: + wpa_printf(MSG_DEBUG, "nl80211: control port frame tx status, cookie=%lu", nla_get_u64(tb[NL80211_ATTR_COOKIE])); + nl80211_control_port_frame_tx_status(drv, tb); + break; default: wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event " "(cmd=%d)", cmd); break; + } } -- 2.27.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap