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

Markus Theil <[email protected]> Wed, 10 Jun 2020 10:32:58 +0200
Newsgroups gmane.linux.drivers.hostap
Message-ID <[email protected]>
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 <[email protected]>
---
 src/drivers/driver_nl80211.c | 43 ++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 17 deletions(-)

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;
 
-- 
2.27.0