]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Add ctrl_iface for enabling/reloading/disabling interface
authorShan Palanisamy <shanp@qca.qualcomm.com>
Fri, 16 Dec 2011 18:42:40 +0000 (20:42 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 25 Aug 2012 10:47:36 +0000 (13:47 +0300)
Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

hostapd/ctrl_iface.c
hostapd/main.c
src/ap/hostapd.c
src/ap/hostapd.h

index c21c8a0173c3932e257e748c1cfb34f440448fac..d6865bb7df51e63d4c6cadfb798757dce52d145b 100644 (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;
index 94b90beb283c17892a6a607e3ef5f8217de5686f..d6c914a9f913fc5215a089dfe656fe7cccde050f 100644 (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;
index 9c0bd9b69b32977b88c24ecebaa95c9e83221153..35ceb02b6abc0228977afa9c66a4a1c6d5bafeef 100644 (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
index 3b79e12867c2b7d1d60a4e4984e99d788d458e9c..2c348322cc811f30eda0c8fd085fae060b85c7db 100644 (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,