AP MLD: Create link based hostapd 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 <ifname>_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>
This commit is contained in:
parent
8625001ce5
commit
61dfd7ae35
5 changed files with 88 additions and 6 deletions
|
@ -4739,18 +4739,26 @@ static char * hostapd_ctrl_iface_path(struct hostapd_data *hapd)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
const char *ctrl_sock_iface;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
ctrl_sock_iface = hapd->ctrl_sock_iface;
|
||||||
|
#else /* CONFIG_IEEE80211BE */
|
||||||
|
ctrl_sock_iface = hapd->conf->iface;
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
if (hapd->conf->ctrl_interface == NULL)
|
if (hapd->conf->ctrl_interface == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = os_strlen(hapd->conf->ctrl_interface) +
|
len = os_strlen(hapd->conf->ctrl_interface) +
|
||||||
os_strlen(hapd->conf->iface) + 2;
|
os_strlen(ctrl_sock_iface) + 2;
|
||||||
|
|
||||||
buf = os_malloc(len);
|
buf = os_malloc(len);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
os_snprintf(buf, len, "%s/%s",
|
os_snprintf(buf, len, "%s/%s",
|
||||||
hapd->conf->ctrl_interface, hapd->conf->iface);
|
hapd->conf->ctrl_interface, ctrl_sock_iface);
|
||||||
buf[len - 1] = '\0';
|
buf[len - 1] = '\0';
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -4866,6 +4874,7 @@ fail:
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
int s = -1;
|
int s = -1;
|
||||||
char *fname = NULL;
|
char *fname = NULL;
|
||||||
|
size_t iflen;
|
||||||
|
|
||||||
if (hapd->ctrl_sock > -1) {
|
if (hapd->ctrl_sock > -1) {
|
||||||
wpa_printf(MSG_DEBUG, "ctrl_iface already exists!");
|
wpa_printf(MSG_DEBUG, "ctrl_iface already exists!");
|
||||||
|
@ -4920,8 +4929,13 @@ fail:
|
||||||
}
|
}
|
||||||
#endif /* ANDROID */
|
#endif /* ANDROID */
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
iflen = os_strlen(hapd->ctrl_sock_iface);
|
||||||
|
#else /* CONFIG_IEEE80211BE */
|
||||||
|
iflen = os_strlen(hapd->conf->iface);
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
if (os_strlen(hapd->conf->ctrl_interface) + 1 +
|
if (os_strlen(hapd->conf->ctrl_interface) + 1 +
|
||||||
os_strlen(hapd->conf->iface) >= sizeof(addr.sun_path))
|
iflen >= sizeof(addr.sun_path))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
s = socket(PF_UNIX, SOCK_DGRAM, 0);
|
s = socket(PF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
|
|
@ -54,7 +54,11 @@ static void usage(void)
|
||||||
fprintf(stderr, "%s\n", hostapd_cli_version);
|
fprintf(stderr, "%s\n", hostapd_cli_version);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\n"
|
"\n"
|
||||||
"usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvBr] "
|
"usage: hostapd_cli [-p<path>] [-i<ifname>] "
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
"[-l<link_id>] "
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
"[-hvBr] "
|
||||||
"[-a<path>] \\\n"
|
"[-a<path>] \\\n"
|
||||||
" [-P<pid file>] [-G<ping interval>] [command..]\n"
|
" [-P<pid file>] [-G<ping interval>] [command..]\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -74,7 +78,11 @@ static void usage(void)
|
||||||
" -B run a daemon in the background\n"
|
" -B run a daemon in the background\n"
|
||||||
" -i<ifname> Interface to listen on (default: first "
|
" -i<ifname> Interface to listen on (default: first "
|
||||||
"interface found in the\n"
|
"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 Operation\n"
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
"\n");
|
||||||
print_help(stderr, NULL);
|
print_help(stderr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2212,12 +2220,15 @@ int main(int argc, char *argv[])
|
||||||
int c;
|
int c;
|
||||||
int daemonize = 0;
|
int daemonize = 0;
|
||||||
int reconnect = 0;
|
int reconnect = 0;
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
int link_id = -1;
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
if (os_program_init())
|
if (os_program_init())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
c = getopt(argc, argv, "a:BhG:i:p:P:rs:v");
|
c = getopt(argc, argv, "a:BhG:i:l:p:P:rs:v");
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
break;
|
break;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -2252,6 +2263,11 @@ int main(int argc, char *argv[])
|
||||||
case 's':
|
case 's':
|
||||||
client_socket_dir = optarg;
|
client_socket_dir = optarg;
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
case 'l':
|
||||||
|
link_id = atoi(optarg);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2285,6 +2301,24 @@ int main(int argc, char *argv[])
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
if (link_id >= 0 && ctrl_ifname) {
|
||||||
|
int ret;
|
||||||
|
char buf[300];
|
||||||
|
|
||||||
|
ret = os_snprintf(buf, sizeof(buf), "%s_%s%d",
|
||||||
|
ctrl_ifname, WPA_CTRL_IFACE_LINK_NAME,
|
||||||
|
link_id);
|
||||||
|
if (os_snprintf_error(sizeof(buf), ret))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
os_free(ctrl_ifname);
|
||||||
|
ctrl_ifname = os_strdup(buf);
|
||||||
|
link_id = -1;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
hostapd_cli_reconnect(ctrl_ifname);
|
hostapd_cli_reconnect(ctrl_ifname);
|
||||||
if (ctrl_conn) {
|
if (ctrl_conn) {
|
||||||
if (warning_displayed)
|
if (warning_displayed)
|
||||||
|
|
|
@ -1824,12 +1824,36 @@ int hostapd_set_acl(struct hostapd_data *hapd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_set_ctrl_sock_iface(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (hapd->conf->mld_ap) {
|
||||||
|
ret = os_snprintf(hapd->ctrl_sock_iface,
|
||||||
|
sizeof(hapd->ctrl_sock_iface), "%s_%s%d",
|
||||||
|
hapd->conf->iface, WPA_CTRL_IFACE_LINK_NAME,
|
||||||
|
hapd->mld_link_id);
|
||||||
|
if (os_snprintf_error(sizeof(hapd->ctrl_sock_iface), ret))
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
os_strlcpy(hapd->ctrl_sock_iface, hapd->conf->iface,
|
||||||
|
sizeof(hapd->ctrl_sock_iface));
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int start_ctrl_iface_bss(struct hostapd_data *hapd)
|
static int start_ctrl_iface_bss(struct hostapd_data *hapd)
|
||||||
{
|
{
|
||||||
if (!hapd->iface->interfaces ||
|
if (!hapd->iface->interfaces ||
|
||||||
!hapd->iface->interfaces->ctrl_iface_init)
|
!hapd->iface->interfaces->ctrl_iface_init)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (hostapd_set_ctrl_sock_iface(hapd))
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (hapd->iface->interfaces->ctrl_iface_init(hapd)) {
|
if (hapd->iface->interfaces->ctrl_iface_init(hapd)) {
|
||||||
wpa_printf(MSG_ERROR,
|
wpa_printf(MSG_ERROR,
|
||||||
"Failed to setup control interface for %s",
|
"Failed to setup control interface for %s",
|
||||||
|
@ -1850,6 +1874,10 @@ static int start_ctrl_iface(struct hostapd_iface *iface)
|
||||||
|
|
||||||
for (i = 0; i < iface->num_bss; i++) {
|
for (i = 0; i < iface->num_bss; i++) {
|
||||||
struct hostapd_data *hapd = iface->bss[i];
|
struct hostapd_data *hapd = iface->bss[i];
|
||||||
|
|
||||||
|
if (hostapd_set_ctrl_sock_iface(hapd))
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (iface->interfaces->ctrl_iface_init(hapd)) {
|
if (iface->interfaces->ctrl_iface_init(hapd)) {
|
||||||
wpa_printf(MSG_ERROR,
|
wpa_printf(MSG_ERROR,
|
||||||
"Failed to setup control interface for %s",
|
"Failed to setup control interface for %s",
|
||||||
|
|
|
@ -495,6 +495,10 @@ struct hostapd_data {
|
||||||
/* Cached partner info for ML probe response */
|
/* Cached partner info for ML probe response */
|
||||||
struct mld_link_info partner_links[MAX_NUM_MLD_LINKS];
|
struct mld_link_info partner_links[MAX_NUM_MLD_LINKS];
|
||||||
|
|
||||||
|
/* 5 characters for "_link", up to 2 characters for <link ID>, so in
|
||||||
|
* total, additional 7 characters required. */
|
||||||
|
char ctrl_sock_iface[IFNAMSIZ + 7 + 1];
|
||||||
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
u8 eht_mld_link_removal_count;
|
u8 eht_mld_link_removal_count;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define WPA_CTRL_IFACE_LINK_NAME "link"
|
||||||
|
|
||||||
/* wpa_supplicant control interface - fixed message prefixes */
|
/* wpa_supplicant control interface - fixed message prefixes */
|
||||||
|
|
||||||
/** Interactive request for identity/password/pin */
|
/** Interactive request for identity/password/pin */
|
||||||
|
|
Loading…
Add table
Reference in a new issue