From bb2b281115fb61ba33cd32655dd53f5d9373ab01 Mon Sep 17 00:00:00 2001 From: Hanan Arshad Date: Tue, 4 Mar 2025 14:50:20 +0500 Subject: [PATCH] hostap: Add support for multiple interfaces in WPA supplicant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Description: The current WPA supplicant implementation in Zephyr does not support multiple interfaces because it uses a single global control channel for interface communication. Since each interface (wpa_s instance) operates independently, this limitation prevents proper handling of multiple virtual interfaces (VIFs). This commit modifies WPA supplicant to support multiple interfaces by: * Removing the single global control channel. * Introducing a new ctrl_conn member in the wpa_s structure. * Assigning a separate ctrl_conn for each interface instance, enabling independent communication between WPA supplicant and Zephyr’s network layer. With this change, each virtual interface can now communicate with the control layer independently, allowing the coexistence of multiple VIFs. Signed-off-by: Hanan Arshad --- src/common/wpa_ctrl.h | 1 - wpa_supplicant/wpa_cli_cmds.c | 6 ++--- wpa_supplicant/wpa_cli_zephyr.c | 39 +++++++++++++++---------------- wpa_supplicant/wpa_cli_zephyr.h | 18 +++++++------- wpa_supplicant/wpa_supplicant_i.h | 4 ++++ 5 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index ad932456e8..8cd82bbbfe 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -12,7 +12,6 @@ #ifdef __cplusplus extern "C" { #endif -extern struct wpa_ctrl *ctrl_conn; extern char *ifname_prefix; /* wpa_supplicant control interface - fixed message prefixes */ diff --git a/wpa_supplicant/wpa_cli_cmds.c b/wpa_supplicant/wpa_cli_cmds.c index 95dc32df79..b65a8a7190 100644 --- a/wpa_supplicant/wpa_cli_cmds.c +++ b/wpa_supplicant/wpa_cli_cmds.c @@ -489,7 +489,7 @@ static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, const char *cmd, size_t len; int ret; - if (ctrl_conn == NULL) { + if (ctrl == NULL) { wpa_printf(MSG_INFO, "Not connected to hostapd - command dropped.\n"); return -1; } @@ -2122,7 +2122,7 @@ static int wpa_ctrl_command_p2p_peer(struct wpa_ctrl *ctrl, const char *cmd, size_t len; int ret; - if (ctrl_conn == NULL) + if (ctrl == NULL) return -1; len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, @@ -2817,7 +2817,7 @@ static int wpa_ctrl_command_bss(struct wpa_ctrl *ctrl, const char *cmd) size_t len; int ret, id = -1; - if (!ctrl_conn) + if (ctrl == NULL) return -1; len = sizeof(buf) - 1; ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len, diff --git a/wpa_supplicant/wpa_cli_zephyr.c b/wpa_supplicant/wpa_cli_zephyr.c index 00a37f566e..e7297e6a60 100644 --- a/wpa_supplicant/wpa_cli_zephyr.c +++ b/wpa_supplicant/wpa_cli_zephyr.c @@ -30,7 +30,6 @@ #define DEFAULT_IFNAME "wlan0" #define MAX_ARGS 32 -struct wpa_ctrl *ctrl_conn; struct wpa_ctrl *global_ctrl_conn; char *ifname_prefix = NULL; extern struct wpa_global *global; @@ -46,7 +45,7 @@ static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, const char *cmd, int print, size_t len; int ret; - if (ctrl_conn == NULL && global_ctrl_conn == NULL) { + if (ctrl == NULL && global_ctrl_conn == NULL) { wpa_printf(MSG_ERROR, "Not connected to wpa_supplicant - command dropped."); return -1; } @@ -93,31 +92,31 @@ static int wpa_ctrl_command_resp(struct wpa_ctrl *ctrl, const char *cmd, char *r return _wpa_ctrl_command(ctrl, cmd, 0, resp); } -int zephyr_wpa_cli_cmd_resp(const char *cmd, char *resp) +int zephyr_wpa_cli_cmd_resp(struct wpa_ctrl *ctrl, const char *cmd, char *resp) { - return _wpa_ctrl_command(ctrl_conn, cmd, 1, resp); + return _wpa_ctrl_command(ctrl, cmd, 1, resp); } static void wpa_cli_close_connection(struct wpa_supplicant *wpa_s) { int ret; - if (ctrl_conn == NULL) + if (wpa_s->ctrl_conn == NULL) return; - ret = wpa_ctrl_detach(ctrl_conn); + ret = wpa_ctrl_detach(wpa_s->ctrl_conn); if (ret < 0) { wpa_printf(MSG_INFO, "Failed to detach from wpa_supplicant: %s", strerror(errno)); } - wpa_ctrl_close(ctrl_conn); - ctrl_conn = NULL; + wpa_ctrl_close(wpa_s->ctrl_conn); + wpa_s->ctrl_conn = NULL; } static int wpa_cli_open_connection(struct wpa_supplicant *wpa_s) { - ctrl_conn = wpa_ctrl_open(wpa_s->ctrl_iface->sock_pair[0]); - if (ctrl_conn == NULL) { + wpa_s->ctrl_conn = wpa_ctrl_open(wpa_s->ctrl_iface->sock_pair[0]); + if (wpa_s->ctrl_conn == NULL) { wpa_printf(MSG_ERROR, "Failed to open control connection to %d", wpa_s->ctrl_iface->sock_pair[0]); return -1; @@ -325,12 +324,12 @@ void zephyr_wpa_ctrl_deinit(void *wpa_s) wpa_cli_close_connection((struct wpa_supplicant *)wpa_s); } -int zephyr_wpa_ctrl_zephyr_cmd(int argc, const char *argv[]) +int zephyr_wpa_ctrl_zephyr_cmd(struct wpa_ctrl *ctrl, int argc, const char *argv[]) { - return wpa_request(ctrl_conn, argc , (char **) argv); + return wpa_request(ctrl, argc , (char **) argv); } -int zephyr_wpa_cli_cmd_v(const char *fmt, ...) +int zephyr_wpa_cli_cmd_v(struct wpa_ctrl *ctrl, const char *fmt, ...) { va_list cmd_args; int argc; @@ -347,15 +346,15 @@ int zephyr_wpa_cli_cmd_v(const char *fmt, ...) for (int i = 0; i < argc; i++) wpa_printf(MSG_DEBUG, "argv[%d]: %s", i, argv[i]); - return zephyr_wpa_ctrl_zephyr_cmd(argc, argv); + return zephyr_wpa_ctrl_zephyr_cmd(ctrl, argc, argv); } -int z_wpa_ctrl_add_network(struct add_network_resp *resp) +int z_wpa_ctrl_add_network(struct wpa_ctrl *ctrl, struct add_network_resp *resp) { int ret; char buf[MAX_RESPONSE_SIZE] = {0}; - ret = wpa_ctrl_command_resp(ctrl_conn, "ADD_NETWORK", buf); + ret = wpa_ctrl_command_resp(ctrl, "ADD_NETWORK", buf); if (ret) { return ret; } @@ -370,12 +369,12 @@ int z_wpa_ctrl_add_network(struct add_network_resp *resp) return 0; } -int z_wpa_ctrl_signal_poll(struct signal_poll_resp *resp) +int z_wpa_ctrl_signal_poll(struct wpa_ctrl *ctrl, struct signal_poll_resp *resp) { int ret; char buf[MAX_RESPONSE_SIZE] = {0}; - ret = wpa_ctrl_command_resp(ctrl_conn, "SIGNAL_POLL", buf); + ret = wpa_ctrl_command_resp(ctrl, "SIGNAL_POLL", buf); if (ret) { return ret; } @@ -390,12 +389,12 @@ int z_wpa_ctrl_signal_poll(struct signal_poll_resp *resp) return 0; } -int z_wpa_ctrl_status(struct status_resp *resp) +int z_wpa_ctrl_status(struct wpa_ctrl *ctrl, struct status_resp *resp) { int ret; char buf[MAX_RESPONSE_SIZE] = {0}; - ret = wpa_ctrl_command_resp(ctrl_conn, "STATUS", buf); + ret = wpa_ctrl_command_resp(ctrl, "STATUS", buf); if (ret) { return ret; } diff --git a/wpa_supplicant/wpa_cli_zephyr.h b/wpa_supplicant/wpa_cli_zephyr.h index 86bd0e86e6..538f11f90d 100644 --- a/wpa_supplicant/wpa_cli_zephyr.h +++ b/wpa_supplicant/wpa_cli_zephyr.h @@ -26,17 +26,19 @@ struct status_resp { char ssid[SSID_MAX_LEN + 1]; }; +struct wpa_ctrl; + /* Public APIs */ int zephyr_wpa_ctrl_init(void *wpa_s); void zephyr_wpa_ctrl_deinit(void *wpa_s); -int zephyr_wpa_ctrl_zephyr_cmd(int argc, const char *argv[]); -int zephyr_wpa_cli_cmd_v(const char *fmt, ...); -int zephyr_wpa_cli_cmd_resp(const char *cmd, char *resp); - -int z_wpa_ctrl_add_network(struct add_network_resp *resp); -int z_wpa_ctrl_signal_poll(struct signal_poll_resp *resp); -int z_wpa_ctrl_status(struct status_resp *resp); - +int zephyr_wpa_ctrl_zephyr_cmd(struct wpa_ctrl *ctrl, int argc, const char *argv[]); +int zephyr_wpa_cli_cmd_v(struct wpa_ctrl *ctrl, const char *fmt, ...); +int zephyr_wpa_cli_cmd_resp(struct wpa_ctrl *ctrl, const char *cmd, char *resp); + +int z_wpa_ctrl_add_network(struct wpa_ctrl *ctrl, struct add_network_resp *resp); +int z_wpa_ctrl_signal_poll(struct wpa_ctrl *ctrl, struct signal_poll_resp *resp); +int z_wpa_ctrl_status(struct wpa_ctrl *ctrl, struct status_resp *resp); + /* Global control interface */ int zephyr_global_wpa_ctrl_init(void); void zephyr_global_wpa_ctrl_deinit(void); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 0d0e4c3304..b95cf3bcef 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -36,6 +36,7 @@ struct wpa_sm; struct wpa_supplicant; struct ibss_rsn; struct scan_info; +struct wpa_ctrl; struct wpa_bss; struct wpa_scan_results; struct hostapd_hw_modes; @@ -700,6 +701,9 @@ struct wpa_supplicant { unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; + /* wpa_ctrl for each wpa_s */ + struct wpa_ctrl *ctrl_conn; + struct wpa_ctrl *mon_conn; #ifdef CONFIG_MATCH_IFACE int matched; #endif /* CONFIG_MATCH_IFACE */