diff mbox series

[v2,3/6] nl80211: use control port tx (status) in AP mode if possible

Message ID 20200610083301.7496-4-markus.theil@tu-ilmenau.de
State Accepted
Headers show
Series nl80211: add support for control port tx status | expand

Commit Message

Markus Theil June 10, 2020, 8:32 a.m. UTC
This patch checks if nl80211 ctrl port tx status is available
in kernel and enable control port tx if so. With this feature,
nl80211 control path is able to provide the same feature set
as nl80211 (mgmt) + AF_PACKET socket (ctrl) before.

For debugging and testing, this can explicitly be disabled with
the driver parameter control_port_ap=0.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
 src/drivers/driver_nl80211.c | 43 ++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 17 deletions(-)
diff mbox series

Patch

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index e5172769a..ade014946 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -2135,25 +2135,29 @@  static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
 	if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1, driver_params))
 		goto failed;
 
-	drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
-	if (drv->eapol_tx_sock < 0)
-		goto failed;
+	if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS) {
+		drv->control_port_ap = 1;
+	} else {
+		drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
+		if (drv->eapol_tx_sock < 0)
+			goto failed;
 
-	if (drv->data_tx_status) {
-		int enabled = 1;
+		if (drv->data_tx_status) {
+			int enabled = 1;
 
-		if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS,
-			       &enabled, sizeof(enabled)) < 0) {
-			wpa_printf(MSG_DEBUG,
-				"nl80211: wifi status sockopt failed\n");
-			drv->data_tx_status = 0;
-			if (!drv->use_monitor)
-				drv->capa.flags &=
-					~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
-		} else {
-			eloop_register_read_sock(drv->eapol_tx_sock,
-				wpa_driver_nl80211_handle_eapol_tx_status,
-				drv, NULL);
+			if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS,
+				       &enabled, sizeof(enabled)) < 0) {
+				wpa_printf(MSG_DEBUG,
+					"nl80211: wifi status sockopt failed\n");
+				drv->data_tx_status = 0;
+				if (!drv->use_monitor)
+					drv->capa.flags &=
+						~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
+			} else {
+				eloop_register_read_sock(drv->eapol_tx_sock,
+					wpa_driver_nl80211_handle_eapol_tx_status,
+					drv, NULL);
+			}
 		}
 	}
 
@@ -8269,6 +8273,11 @@  static int nl80211_set_param(void *priv, const char *param)
 	if (os_strstr(param, "control_port_ap=1"))
 		drv->control_port_ap = 1;
 
+	if (os_strstr(param, "control_port_ap=0")) {
+		drv->capa.flags2 &= ~WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS;
+		drv->control_port_ap = 0;
+	}
+
 	if (os_strstr(param, "full_ap_client_state=0"))
 		drv->capa.flags &= ~WPA_DRIVER_FLAGS_FULL_AP_CLIENT_STATE;