hostapd: Add ctrl_iface for enabling/reloading/disabling interface

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Shan Palanisamy 2011-12-16 20:42:40 +02:00 committed by Jouni Malinen
parent c90fd48514
commit 7554565299
4 changed files with 147 additions and 15 deletions

View file

@ -747,6 +747,36 @@ static int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd,
}
static int hostapd_ctrl_iface_enable(struct hostapd_iface *iface)
{
if (hostapd_enable_iface(iface) < 0) {
wpa_printf(MSG_ERROR, "Enabling of interface failed");
return -1;
}
return 0;
}
static int hostapd_ctrl_iface_reload(struct hostapd_iface *iface)
{
if (hostapd_reload_iface(iface) < 0) {
wpa_printf(MSG_ERROR, "Reloading of interface failed");
return -1;
}
return 0;
}
static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface)
{
if (hostapd_disable_iface(iface) < 0) {
wpa_printf(MSG_ERROR, "Disabling of interface failed");
return -1;
}
return 0;
}
static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
void *sock_ctx)
{
@ -899,6 +929,15 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
} else if (os_strncmp(buf, "GET ", 4) == 0) {
reply_len = hostapd_ctrl_iface_get(hapd, buf + 4, reply,
reply_size);
} else if (os_strncmp(buf, "ENABLE", 6) == 0) {
if (hostapd_ctrl_iface_enable(hapd->iface))
reply_len = -1;
} else if (os_strncmp(buf, "RELOAD", 6) == 0) {
if (hostapd_ctrl_iface_reload(hapd->iface))
reply_len = -1;
} else if (os_strncmp(buf, "DISABLE", 7) == 0) {
if (hostapd_ctrl_iface_disable(hapd->iface))
reply_len = -1;
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16;

View file

@ -279,21 +279,6 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
}
static void hostapd_interface_deinit_free(struct hostapd_iface *iface)
{
const struct wpa_driver_ops *driver;
void *drv_priv;
if (iface == NULL)
return;
driver = iface->bss[0]->driver;
drv_priv = iface->bss[0]->drv_priv;
hostapd_interface_deinit(iface);
if (driver && driver->hapd_deinit && drv_priv)
driver->hapd_deinit(drv_priv);
hostapd_interface_free(iface);
}
static struct hostapd_iface *
hostapd_interface_init(struct hapd_interfaces *interfaces,
const char *config_fname, int debug)
@ -565,6 +550,7 @@ int main(int argc, char *argv[])
interfaces.for_each_interface = hostapd_for_each_interface;
interfaces.ctrl_iface_init = hostapd_ctrl_iface_init;
interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit;
interfaces.driver_init = hostapd_driver_init;
interfaces.global_iface_path = NULL;
interfaces.global_iface_name = NULL;
interfaces.global_ctrl_sock = -1;

View file

@ -1048,6 +1048,108 @@ void hostapd_interface_free(struct hostapd_iface *iface)
}
#ifdef HOSTAPD
void hostapd_interface_deinit_free(struct hostapd_iface *iface)
{
const struct wpa_driver_ops *driver;
void *drv_priv;
if (iface == NULL)
return;
driver = iface->bss[0]->driver;
drv_priv = iface->bss[0]->drv_priv;
hostapd_interface_deinit(iface);
if (driver && driver->hapd_deinit && drv_priv)
driver->hapd_deinit(drv_priv);
hostapd_interface_free(iface);
}
int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
{
if (hapd_iface->bss[0]->drv_priv != NULL) {
wpa_printf(MSG_ERROR, "Interface %s already enabled",
hapd_iface->conf->bss[0].iface);
return -1;
}
wpa_printf(MSG_DEBUG, "Enable interface %s",
hapd_iface->conf->bss[0].iface);
if (hapd_iface->interfaces == NULL ||
hapd_iface->interfaces->driver_init == NULL ||
hapd_iface->interfaces->driver_init(hapd_iface) ||
hostapd_setup_interface(hapd_iface)) {
hostapd_interface_deinit_free(hapd_iface);
return -1;
}
return 0;
}
int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
{
size_t j;
wpa_printf(MSG_DEBUG, "Reload interface %s",
hapd_iface->conf->bss[0].iface);
for (j = 0; j < hapd_iface->num_bss; j++) {
hostapd_flush_old_stations(hapd_iface->bss[j],
WLAN_REASON_PREV_AUTH_NOT_VALID);
#ifndef CONFIG_NO_RADIUS
/* TODO: update dynamic data based on changed configuration
* items (e.g., open/close sockets, etc.) */
radius_client_flush(hapd_iface->bss[j]->radius, 0);
#endif /* CONFIG_NO_RADIUS */
hostapd_reload_bss(hapd_iface->bss[j]);
}
return 0;
}
int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
{
size_t j;
struct hostapd_bss_config *bss = hapd_iface->bss[0]->conf;
const struct wpa_driver_ops *driver;
void *drv_priv;
if (hapd_iface == NULL)
return -1;
driver = hapd_iface->bss[0]->driver;
drv_priv = hapd_iface->bss[0]->drv_priv;
/* whatever hostapd_interface_deinit does */
for (j = 0; j < hapd_iface->num_bss; j++) {
struct hostapd_data *hapd = hapd_iface->bss[j];
hostapd_free_stas(hapd);
hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
hostapd_clear_wep(hapd);
hostapd_free_hapd_data(hapd);
}
if (driver && driver->hapd_deinit && drv_priv) {
driver->hapd_deinit(drv_priv);
hapd_iface->bss[0]->drv_priv = NULL;
}
/* From hostapd_cleanup_iface: These were initialized in
* hostapd_setup_interface and hostapd_setup_interface_complete
*/
hostapd_cleanup_iface_partial(hapd_iface);
bss->wpa = 0;
bss->wpa_key_mgmt = -1;
bss->wpa_pairwise = -1;
wpa_printf(MSG_DEBUG, "Interface %s disabled", bss->iface);
return 0;
}
#endif /* HOSTAPD */
/**
* hostapd_new_assoc_sta - Notify that a new station associated with the AP
* @hapd: Pointer to BSS data

View file

@ -33,6 +33,7 @@ struct hapd_interfaces {
int (*for_each_interface)(struct hapd_interfaces *interfaces,
int (*cb)(struct hostapd_iface *iface,
void *ctx), void *ctx);
int (*driver_init)(struct hostapd_iface *iface);
size_t count;
int global_ctrl_sock;
@ -269,6 +270,10 @@ void hostapd_interface_deinit(struct hostapd_iface *iface);
void hostapd_interface_free(struct hostapd_iface *iface);
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
int reassoc);
void hostapd_interface_deinit_free(struct hostapd_iface *iface);
int hostapd_enable_iface(struct hostapd_iface *hapd_iface);
int hostapd_reload_iface(struct hostapd_iface *hapd_iface);
int hostapd_disable_iface(struct hostapd_iface *hapd_iface);
/* utils.c */
int hostapd_register_probereq_cb(struct hostapd_data *hapd,