[PATCH v2 2/6] nl80211: handle control port tx status events over nl80211

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux