[RFC 1/2] hostapd: Allow enabling and disabling of active BSSes

Yogesh Ashok Powar yogeshp
Tue Nov 30 08:46:04 PST 2010


Currently, when an ap interface is brought down using ifconfig, hostapd is not
disabling the corresponding bss. Correspondingly, when the interface is brought
back up, hostapd does not restart the bss. Due to this, when an interface is
brought back up, beaconing does not begin. With this change, bringing down the
interface will disable the corresponding bss and restart the bss on bringing the
interface up using ifconfig.

Signed-off-by: Yogesh Ashok Powar <yogeshp at marvell.com>
---
 hostapd/main.c         |    1 +
 src/ap/drv_callbacks.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/ap/hostapd.c       |   42 ++++++++++++++++++++++++++++++++++++++
 src/ap/hostapd.h       |    4 +++
 src/drivers/driver.h   |    8 +++++++
 5 files changed, 107 insertions(+), 0 deletions(-)

diff --git a/hostapd/main.c b/hostapd/main.c
index 9c532d4..91ebf40 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -198,6 +198,7 @@ static struct hostapd_iface * hostapd_init(const char *config_file)
 	hapd_iface->conf = conf;
 
 	hapd_iface->num_bss = conf->num_bss;
+	hapd_iface->real_num_bss = hapd_iface->num_bss;
 	hapd_iface->bss = os_zalloc(conf->num_bss *
 				    sizeof(struct hostapd_data *));
 	if (hapd_iface->bss == NULL)
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 5469d05..a113fe2 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -193,6 +193,45 @@ skip_wpa_check:
 	return 0;
 }
 
+void hostapd_notify_bss_restart(struct hostapd_data *hapd, const char *ifname)
+{
+	int i;
+	char *ssid=NULL;
+	struct hostapd_iface *iface = hapd->iface;
+
+	for(i=0; i < iface->real_num_bss; i++) {
+		if(strncmp(iface->bss[i]->conf->iface, ifname, IFNAMSIZ) == 0) {
+			ssid = iface->bss[i]->conf->ssid.ssid;
+			if (iface->bss[i]->bss_enabled) {
+				wpa_printf(MSG_DEBUG, "RESTART %s (%s)",
+						ifname, ssid);
+				hostapd_restart_bss(iface->bss[i]);
+			} else
+				iface->bss[i]->bss_enabled = 1;
+			break;
+		}
+	}
+}
+
+
+void hostapd_notify_bss_stop(struct hostapd_data *hapd, const char *ifname)
+{
+	int i;
+	char *ssid=NULL;
+	struct hostapd_iface *iface = hapd->iface;
+
+	for(i=0; i < iface->num_bss; i++) {
+		if(strncmp(iface->bss[i]->conf->iface, ifname, IFNAMSIZ) == 0) {
+			ssid = iface->bss[i]->conf->ssid.ssid;
+			if (iface->bss[i]->bss_enabled) {
+				wpa_printf(MSG_DEBUG, "Stop %s (%s)", ifname, ssid);
+				hostapd_stop_bss(iface->bss[i]);
+			}
+			break;
+		}
+	}
+}
+
 
 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
 {
@@ -500,6 +539,19 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 		if (data)
 			hostapd_notif_disassoc(hapd, data->deauth_info.addr);
 		break;
+	case EVENT_INTERFACE_STATUS:
+		break;
+	case EVENT_INTERFACE_DISABLED:
+		if (data)
+			hostapd_notify_bss_stop(hapd,
+					data->interface_status.ifname);
+		break;
+	case EVENT_INTERFACE_ENABLED:
+		if (data)
+			hostapd_notify_bss_restart(hapd,
+					data->interface_status.ifname);
+		break;
+
 	default:
 		wpa_printf(MSG_DEBUG, "Unknown event %d", event);
 		break;
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index b39a9d5..fdbc3bd 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -320,6 +320,48 @@ static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
 	return 0;
 }
 
+int hostapd_restart_bss(struct hostapd_data *hapd)
+{
+	struct hostapd_iface *iface = hapd->iface;
+	void *p=NULL;
+	int i;
+
+	for(i = iface->num_bss; i < iface->real_num_bss; i++) {
+		if(iface->bss[i] == hapd) {
+			p = iface->bss[iface->num_bss];
+			iface->bss[iface->num_bss] = iface->bss[i];
+			iface->bss[i] = p;
+
+			iface->num_bss++;
+			break;
+		}
+	}
+	ieee802_11_set_beacon(hapd);
+
+	return 0;
+}
+
+int hostapd_stop_bss(struct hostapd_data *hapd)
+{
+	int i;
+	struct hostapd_iface *iface = hapd->iface;
+	void *p=NULL;
+
+	hostapd_free_stas(hapd);
+	hostapd_flush_old_stations(hapd);
+
+	for(i=0; i < iface->num_bss; i++) {
+		if (iface->bss[i] == hapd)
+			p = (void *) hapd;
+		else if (p)
+			iface->bss[i-1] = iface->bss[i];
+	}
+	iface->bss[i-1] = (struct hostapd_data *)p;
+
+	iface->num_bss--;
+
+	return 0;
+}
 
 static int hostapd_flush_old_stations(struct hostapd_data *hapd)
 {
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index e2182cc..cbc2cba 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -155,6 +155,7 @@ struct hostapd_data {
 	int noa_start;
 	int noa_duration;
 #endif /* CONFIG_P2P */
+	int bss_enabled;
 };
 
 
@@ -170,6 +171,7 @@ struct hostapd_iface {
 	struct hostapd_config *conf;
 
 	size_t num_bss;
+	size_t real_num_bss;
 	struct hostapd_data **bss;
 
 	int num_ap; /* number of entries in ap_list */
@@ -235,6 +237,8 @@ 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);
+int hostapd_stop_bss(struct hostapd_data *hapd);
+int hostapd_restart_bss(struct hostapd_data *hapd);
 
 /* utils.c */
 int hostapd_register_probereq_cb(struct hostapd_data *hapd,
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 956403a..235fce5 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2423,6 +2423,14 @@ union wpa_event_data {
 	} interface_status;
 
 	/**
+	 * struct interface_up_down - Data for EVENT_INTERFACE_DISABLED and
+	 * EVENT_INTERFACE_ENABLED
+	 */
+	struct interface_up_down {
+		char ifname[100];
+	} interface_up_down;
+
+	/**
 	 * struct pmkid_candidate - Data for EVENT_PMKID_CANDIDATE
 	 */
 	struct pmkid_candidate {
-- 
1.5.4.3





More information about the Hostap mailing list