[PATCH] driver-nl80211: Use wpa_msg to report netlink errors.

greearb at candelatech.com greearb at candelatech.com
Wed Jul 10 11:37:11 PDT 2024


From: Ben Greear <greearb at candelatech.com>

This allows errors to be propagated to listeners instead of
just buried in the logs.

Signed-off-by: Ben Greear <greearb at candelatech.com>
---
 src/drivers/driver_nl80211.c | 55 ++++++++++++++++++++----------------
 src/drivers/driver_nl80211.h | 33 ++++++++++++++++------
 2 files changed, 55 insertions(+), 33 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 4f79ac4b4..c9654d7db 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -349,6 +349,7 @@ struct nl80211_ack_err_args {
 	int err;
 	struct nl_msg *orig_msg;
 	struct nl80211_err_info *err_info;
+	struct wpa_driver_nl80211_data *drv;
 };
 
 static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
@@ -385,8 +386,12 @@ static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
 	if (tb[NLMSGERR_ATTR_MSG]) {
 		len = strnlen((char *) nla_data(tb[NLMSGERR_ATTR_MSG]),
 			      nla_len(tb[NLMSGERR_ATTR_MSG]));
-		wpa_printf(MSG_ERROR, "nl80211: kernel reports: %*s",
-			   len, (char *) nla_data(tb[NLMSGERR_ATTR_MSG]));
+		if (err_args->drv)
+			wpa_msg(err_args->drv->ctx, MSG_ERROR, "nl80211: kernel reports: %*s",
+				len, (char *) nla_data(tb[NLMSGERR_ATTR_MSG]));
+		else
+			wpa_printf(MSG_ERROR, "nl80211: kernel reports: %*s",
+				   len, (char *) nla_data(tb[NLMSGERR_ATTR_MSG]));
 	}
 
 	if (!err_args->err_info)
@@ -491,13 +496,14 @@ out:
 }
 
 
-int send_and_recv(struct nl80211_global *global,
-		  struct nl_sock *nl_handle, struct nl_msg *msg,
-		  int (*valid_handler)(struct nl_msg *, void *),
-		  void *valid_data,
-		  int (*ack_handler_custom)(struct nl_msg *, void *),
-		  void *ack_data,
-		  struct nl80211_err_info *err_info)
+int send_and_recv_glb(struct nl80211_global *global,
+		      struct wpa_driver_nl80211_data *drv, /* may be NULL */
+		      struct nl_sock *nl_handle, struct nl_msg *msg,
+		      int (*valid_handler)(struct nl_msg *, void *),
+		      void *valid_data,
+		      int (*ack_handler_custom)(struct nl_msg *, void *),
+		      void *ack_data,
+		      struct nl80211_err_info *err_info)
 {
 	struct nl_cb *cb, *s_nl_cb;
 	struct nl80211_ack_err_args err;
@@ -539,6 +545,7 @@ int send_and_recv(struct nl80211_global *global,
 	err.err = 1;
 	err.orig_msg = msg;
 	err.err_info = err_info;
+	err.drv = drv;
 
 	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
 	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err.err);
@@ -654,8 +661,8 @@ static int nl_get_multicast_id(struct nl80211_global *global,
 		return -1;
 	}
 
-	ret = send_and_recv(global, global->nl, msg, family_handler, &res,
-			    NULL, NULL, NULL);
+	ret = send_and_recv_glb(global, NULL, global->nl, msg, family_handler, &res,
+				NULL, NULL, NULL);
 	if (ret == 0)
 		ret = res.id;
 	return ret;
@@ -850,7 +857,7 @@ static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
 		return -1;
 	}
 
-	ret = send_and_recv(drv->global, w->nl_beacons, msg, NULL, NULL,
+	ret = send_and_recv(drv, w->nl_beacons, msg, NULL, NULL,
 			    NULL, NULL, NULL);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Register beacons command "
@@ -2461,7 +2468,7 @@ static int nl80211_register_frame(struct i802_bss *bss,
 		return -1;
 	}
 
-	ret = send_and_recv(drv->global, nl_handle, msg, NULL, NULL,
+	ret = send_and_recv(drv, nl_handle, msg, NULL, NULL,
 			    NULL, NULL, NULL);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Register frame command "
@@ -2729,7 +2736,7 @@ static int nl80211_register_spurious_class3(struct i802_bss *bss)
 	int ret;
 
 	msg = nl80211_bss_msg(bss, 0, NL80211_CMD_UNEXPECTED_FRAME);
-	ret = send_and_recv(bss->drv->global, bss->nl_mgmt, msg, NULL, NULL,
+	ret = send_and_recv(bss->drv, bss->nl_mgmt, msg, NULL, NULL,
 			    NULL, NULL, NULL);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Register spurious class3 "
@@ -3806,7 +3813,7 @@ int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
 		return -1;
 	}
 
-	ret = send_and_recv(drv->global, bss->nl_connect, msg,
+	ret = send_and_recv(drv, bss->nl_connect, msg,
 			    NULL, NULL, NULL, NULL, NULL);
 	if (ret) {
 		wpa_dbg(drv->ctx, MSG_INFO,
@@ -5437,7 +5444,7 @@ static int wpa_driver_nl80211_set_ap(void *priv,
 
 	if (nla_put_flag(msg, NL80211_ATTR_SOCKET_OWNER))
 		goto fail;
-	ret = send_and_recv(drv->global, bss->nl_connect, msg, NULL, NULL, NULL,
+	ret = send_and_recv(drv, bss->nl_connect, msg, NULL, NULL, NULL,
 			    NULL, NULL);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
@@ -6235,7 +6242,7 @@ static int nl80211_tx_control_port(void *priv, const u8 *dest,
 
 	os_memset(&ext_arg, 0, sizeof(struct nl80211_ack_ext_arg));
 	ext_arg.ext_data = &cookie;
-	ret = send_and_recv(bss->drv->global, bss->drv->global->nl, msg,
+	ret = send_and_recv(bss->drv, bss->drv->global->nl, msg,
 			    NULL, NULL, ack_handler_cookie, &ext_arg, NULL);
 	if (ret) {
 		wpa_printf(MSG_DEBUG,
@@ -6476,7 +6483,7 @@ static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv,
 	int ret;
 
 	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_IBSS);
-	ret = send_and_recv(drv->global, drv->first_bss->nl_connect, msg, NULL,
+	ret = send_and_recv(drv, drv->first_bss->nl_connect, msg, NULL,
 			    NULL, NULL, NULL, NULL);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
@@ -6655,7 +6662,7 @@ retry:
 
 	if (nla_put_flag(msg, NL80211_ATTR_SOCKET_OWNER))
 		goto fail;
-	ret = send_and_recv(drv->global, drv->first_bss->nl_connect, msg, NULL,
+	ret = send_and_recv(drv, drv->first_bss->nl_connect, msg, NULL,
 			    NULL, NULL, NULL, NULL);
 	msg = NULL;
 	if (ret) {
@@ -7211,7 +7218,7 @@ skip_auth_type:
 
 	if (nla_put_flag(msg, NL80211_ATTR_SOCKET_OWNER))
 		goto fail;
-	ret = send_and_recv(drv->global, bss->nl_connect, msg, NULL, NULL, NULL,
+	ret = send_and_recv(drv, bss->nl_connect, msg, NULL, NULL, NULL,
 			    NULL, NULL);
 	msg = NULL;
 	if (ret) {
@@ -7330,7 +7337,7 @@ static int wpa_driver_nl80211_associate(
 	if (!TEST_FAIL_TAG("assoc")) {
 		if (nla_put_flag(msg, NL80211_ATTR_SOCKET_OWNER))
 			goto fail;
-		ret = send_and_recv(drv->global, drv->first_bss->nl_connect,
+		ret = send_and_recv(drv, drv->first_bss->nl_connect,
 				    msg, NULL, NULL, NULL, NULL, &err_info);
 		msg = NULL;
 	} else {
@@ -11950,7 +11957,7 @@ static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id,
 		/* This test vendor_cmd can be used with nl80211 commands that
 		 * need the connect nl_sock, so use the variant that takes in
 		 * bss->nl_connect as the handle. */
-		ret = send_and_recv(drv->global, bss->nl_connect, msg,
+		ret = send_and_recv(drv, bss->nl_connect, msg,
 				    cmd_reply_handler, buf, NULL, NULL, NULL);
 		if (ret)
 			wpa_printf(MSG_DEBUG, "nl80211: command failed err=%d",
@@ -12425,7 +12432,7 @@ static int nl80211_join_mesh(struct i802_bss *bss,
 
 	if (nla_put_flag(msg, NL80211_ATTR_SOCKET_OWNER))
 		return -1;
-	ret = send_and_recv(drv->global, bss->nl_connect, msg, NULL, NULL, NULL,
+	ret = send_and_recv(drv, bss->nl_connect, msg, NULL, NULL, NULL,
 			    NULL, NULL);
 	msg = NULL;
 	if (ret) {
@@ -12483,7 +12490,7 @@ static int wpa_driver_nl80211_leave_mesh(void *priv)
 
 	wpa_printf(MSG_DEBUG, "nl80211: mesh leave (ifindex=%d)", drv->ifindex);
 	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_MESH);
-	ret = send_and_recv(drv->global, bss->nl_connect, msg, NULL, NULL, NULL,
+	ret = send_and_recv(drv, bss->nl_connect, msg, NULL, NULL, NULL,
 			    NULL, NULL);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: mesh leave failed: ret=%d (%s)",
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index 4958e163e..5e42e7936 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -289,19 +289,34 @@ struct nl_msg * nl80211_drv_msg(struct wpa_driver_nl80211_data *drv, int flags,
 				uint8_t cmd);
 struct nl_msg * nl80211_bss_msg(struct i802_bss *bss, int flags, uint8_t cmd);
 
-int send_and_recv(struct nl80211_global *global,
-		  struct nl_sock *nl_handle, struct nl_msg *msg,
-		  int (*valid_handler)(struct nl_msg *, void *),
-		  void *valid_data,
-		  int (*ack_handler_custom)(struct nl_msg *, void *),
-		  void *ack_data,
-		  struct nl80211_err_info *err_info);
+int send_and_recv_glb(struct nl80211_global *global,
+		      struct wpa_driver_nl80211_data *drv, /* may be NULL */
+		      struct nl_sock *nl_handle, struct nl_msg *msg,
+		      int (*valid_handler)(struct nl_msg *, void *),
+		      void *valid_data,
+		      int (*ack_handler_custom)(struct nl_msg *, void *),
+		      void *ack_data,
+		      struct nl80211_err_info *err_info);
+
+static inline int
+send_and_recv(struct wpa_driver_nl80211_data *drv,
+	      struct nl_sock *nl_handle, struct nl_msg *msg,
+	      int (*valid_handler)(struct nl_msg *, void *),
+	      void *valid_data,
+	      int (*ack_handler_custom)(struct nl_msg *, void *),
+	      void *ack_data,
+	      struct nl80211_err_info *err_info)
+{
+	return send_and_recv_glb(drv->global, drv, nl_handle, msg,
+				 valid_handler, valid_data,
+				 ack_handler_custom, ack_data, err_info);
+}
 
 static inline int
 send_and_recv_cmd(struct wpa_driver_nl80211_data *drv,
 		  struct nl_msg *msg)
 {
-	return send_and_recv(drv->global, drv->global->nl, msg,
+	return send_and_recv(drv, drv->global->nl, msg,
 			     NULL, NULL, NULL, NULL, NULL);
 }
 
@@ -311,7 +326,7 @@ send_and_recv_resp(struct wpa_driver_nl80211_data *drv,
 		   int (*valid_handler)(struct nl_msg *, void *),
 		   void *valid_data)
 {
-	return send_and_recv(drv->global, drv->global->nl, msg,
+	return send_and_recv(drv, drv->global->nl, msg,
 			     valid_handler, valid_data, NULL, NULL, NULL);
 }
 
-- 
2.42.0




More information about the Hostap mailing list