| From 166ae43a8066cbc70d5d990cfd29cb6c4c2afc67 Mon Sep 17 00:00:00 2001 |
| From: Karthikeyan Kathirvel <quic_kathirve@quicinc.com> |
| Date: Tue, 23 Apr 2024 11:01:23 +0530 |
| Subject: [PATCH 001/126] ctrl_iface: create link based hapd control sockets |
| |
| Create link based control sockets to access the link based commands |
| through hostapd_cli. This will create the link interfaces in the name of |
| wlan<X>_link<X> |
| |
| Example: |
| To fetch link 0 status from wlan0, below command can be used - |
| $ hostapd_cli -i wlan0 -l 0 status |
| |
| On failure of link/interface selection, below error will be observed |
| $ hostapd_cli -i wlan0 -l 2 status |
| Failed to connect to hostapd - wpa_ctrl_open: No such file or directory |
| |
| Signed-off-by: Karthikeyan Kathirvel <quic_kathirve@quicinc.com> |
| Co-developed-by: Aditya Kumar Singh <quic_adisi@quicinc.com> |
| Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com> |
| --- |
| hostapd/ctrl_iface.c | 16 ++++++++++++++-- |
| hostapd/hostapd_cli.c | 30 ++++++++++++++++++++++++++++-- |
| src/ap/hostapd.c | 28 ++++++++++++++++++++++++++++ |
| src/ap/hostapd.h | 1 + |
| src/common/wpa_ctrl.h | 4 ++++ |
| 5 files changed, 75 insertions(+), 4 deletions(-) |
| |
| diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c |
| index 39b9ef59d..3fa33be7a 100644 |
| --- a/hostapd/ctrl_iface.c |
| +++ b/hostapd/ctrl_iface.c |
| @@ -4687,18 +4687,26 @@ static char * hostapd_ctrl_iface_path(struct hostapd_data *hapd) |
| { |
| char *buf; |
| size_t len; |
| + char *ctrl_sock_iface; |
| + |
| +#ifdef CONFIG_IEEE80211BE |
| + ctrl_sock_iface = hapd->ctrl_sock_iface; |
| +#else |
| + ctrl_sock_iface = hapd->conf->iface; |
| +#endif /* CONFIG_IEEE80211BE */ |
| |
| if (hapd->conf->ctrl_interface == NULL) |
| return NULL; |
| |
| len = os_strlen(hapd->conf->ctrl_interface) + |
| - os_strlen(hapd->conf->iface) + 2; |
| + os_strlen(ctrl_sock_iface) + 2; |
| + |
| buf = os_malloc(len); |
| if (buf == NULL) |
| return NULL; |
| |
| os_snprintf(buf, len, "%s/%s", |
| - hapd->conf->ctrl_interface, hapd->conf->iface); |
| + hapd->conf->ctrl_interface, ctrl_sock_iface); |
| buf[len - 1] = '\0'; |
| return buf; |
| } |
| @@ -4869,7 +4877,11 @@ fail: |
| #endif /* ANDROID */ |
| |
| if (os_strlen(hapd->conf->ctrl_interface) + 1 + |
| +#ifdef CONFIG_IEEE80211BE |
| + os_strlen(hapd->ctrl_sock_iface) >= sizeof(addr.sun_path)) |
| +#else |
| os_strlen(hapd->conf->iface) >= sizeof(addr.sun_path)) |
| +#endif /* CONFIG_IEEE80211BE */ |
| goto fail; |
| |
| s = socket(PF_UNIX, SOCK_DGRAM, 0); |
| diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c |
| index eb8a38350..f05a734fe 100644 |
| --- a/hostapd/hostapd_cli.c |
| +++ b/hostapd/hostapd_cli.c |
| @@ -54,7 +54,11 @@ static void usage(void) |
| fprintf(stderr, "%s\n", hostapd_cli_version); |
| fprintf(stderr, |
| "\n" |
| +#ifdef CONFIG_IEEE80211BE |
| + "usage: hostapd_cli [-p<path>] [-i<ifname>] [-l<link_id>] [-hvBr] " |
| +#else |
| "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvBr] " |
| +#endif /* CONFIG_IEEE80211BE */ |
| "[-a<path>] \\\n" |
| " [-P<pid file>] [-G<ping interval>] [command..]\n" |
| "\n" |
| @@ -74,7 +78,12 @@ static void usage(void) |
| " -B run a daemon in the background\n" |
| " -i<ifname> Interface to listen on (default: first " |
| "interface found in the\n" |
| - " socket path)\n\n"); |
| + " socket path)\n" |
| +#ifdef CONFIG_IEEE80211BE |
| + " -l<link_id> Link ID of the interface in case of Multi-Link\n" |
| + " Operation\n" |
| +#endif /* CONFIG_IEEE80211BE */ |
| + "\n"); |
| print_help(stderr, NULL); |
| } |
| |
| @@ -2205,19 +2214,26 @@ static void hostapd_cli_action(struct wpa_ctrl *ctrl) |
| eloop_unregister_read_sock(fd); |
| } |
| |
| - |
| int main(int argc, char *argv[]) |
| { |
| int warning_displayed = 0; |
| int c; |
| int daemonize = 0; |
| int reconnect = 0; |
| +#ifdef CONFIG_IEEE80211BE |
| + int link_id = -1; |
| + char buf[300]; |
| +#endif /* CONFIG_IEEE80211BE */ |
| |
| if (os_program_init()) |
| return -1; |
| |
| for (;;) { |
| +#ifdef CONFIG_IEEE80211BE |
| + c = getopt(argc, argv, "a:BhG:i:l:p:P:rs:v"); |
| +#else |
| c = getopt(argc, argv, "a:BhG:i:p:P:rs:v"); |
| +#endif /* CONFIG_IEEE80211BE */ |
| if (c < 0) |
| break; |
| switch (c) { |
| @@ -2252,6 +2268,16 @@ int main(int argc, char *argv[]) |
| case 's': |
| client_socket_dir = optarg; |
| break; |
| +#ifdef CONFIG_IEEE80211BE |
| + case 'l': |
| + link_id = atoi(optarg); |
| + os_memset(buf, '\0', sizeof(buf)); |
| + os_snprintf(buf, sizeof(buf), "%s_%s%d", |
| + ctrl_ifname, WPA_CTRL_IFACE_LINK_NAME, link_id); |
| + os_free(ctrl_ifname); |
| + ctrl_ifname = os_strdup(buf); |
| + break; |
| +#endif /* CONFIG_IEEE80211BE */ |
| default: |
| usage(); |
| return -1; |
| diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c |
| index a05de030d..c819c30cf 100644 |
| --- a/src/ap/hostapd.c |
| +++ b/src/ap/hostapd.c |
| @@ -1808,12 +1808,37 @@ int hostapd_set_acl(struct hostapd_data *hapd) |
| } |
| |
| |
| +static void hostapd_set_ctrl_sock_iface(struct hostapd_data *hapd) |
| +{ |
| +#ifdef CONFIG_IEEE80211BE |
| + os_memset(hapd->ctrl_sock_iface, '\0', |
| + sizeof(hapd->ctrl_sock_iface)); |
| + os_strlcpy(hapd->ctrl_sock_iface, hapd->conf->iface, |
| + sizeof(hapd->ctrl_sock_iface)); |
| + |
| + if (hapd->conf->mld_ap) { |
| + char buf[128]; |
| + |
| + os_memset(buf, '\0', sizeof(buf)); |
| + os_snprintf(buf, sizeof(buf), "%s_%s%d", |
| + hapd->conf->iface, WPA_CTRL_IFACE_LINK_NAME, |
| + hapd->mld_link_id); |
| + os_memset(hapd->ctrl_sock_iface, '\0', |
| + sizeof(hapd->ctrl_sock_iface)); |
| + os_strlcpy(hapd->ctrl_sock_iface, buf, sizeof(buf)); |
| + } |
| +#endif /* CONFIG_IEEE80211BE */ |
| +} |
| + |
| + |
| static int start_ctrl_iface_bss(struct hostapd_data *hapd) |
| { |
| if (!hapd->iface->interfaces || |
| !hapd->iface->interfaces->ctrl_iface_init) |
| return 0; |
| |
| + hostapd_set_ctrl_sock_iface(hapd); |
| + |
| if (hapd->iface->interfaces->ctrl_iface_init(hapd)) { |
| wpa_printf(MSG_ERROR, |
| "Failed to setup control interface for %s", |
| @@ -1834,6 +1859,9 @@ static int start_ctrl_iface(struct hostapd_iface *iface) |
| |
| for (i = 0; i < iface->num_bss; i++) { |
| struct hostapd_data *hapd = iface->bss[i]; |
| + |
| + hostapd_set_ctrl_sock_iface(hapd); |
| + |
| if (iface->interfaces->ctrl_iface_init(hapd)) { |
| wpa_printf(MSG_ERROR, |
| "Failed to setup control interface for %s", |
| diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h |
| index dcf395ca5..34a665562 100644 |
| --- a/src/ap/hostapd.h |
| +++ b/src/ap/hostapd.h |
| @@ -476,6 +476,7 @@ struct hostapd_data { |
| struct hostapd_mld *mld; |
| struct dl_list link; |
| u8 mld_link_id; |
| + char ctrl_sock_iface[IFNAMSIZ + 1]; |
| #ifdef CONFIG_TESTING_OPTIONS |
| u8 eht_mld_link_removal_count; |
| #endif /* CONFIG_TESTING_OPTIONS */ |
| diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h |
| index f6142501e..865ac6d91 100644 |
| --- a/src/common/wpa_ctrl.h |
| +++ b/src/common/wpa_ctrl.h |
| @@ -674,4 +674,8 @@ char * wpa_ctrl_get_remote_ifname(struct wpa_ctrl *ctrl); |
| } |
| #endif |
| |
| +#ifdef CONFIG_IEEE80211BE |
| +#define WPA_CTRL_IFACE_LINK_NAME "link" |
| +#endif /* CONFIG_IEEE80211BE */ |
| + |
| #endif /* WPA_CTRL_H */ |
| -- |
| 2.18.0 |
| |