[PATCH v2 7/7] wpa_supplicant: parameterize bss expiration age+count

Sam Leffler sleffler
Fri Mar 18 13:53:54 PDT 2011


Replace compile-time BSS cache expiration age and scan count by config
parameters that can be set via wpa_cli and the new DBus API.  The latter
is done with interface properties BSSExpireAge and BSSExpireCount.
---
 wpa_supplicant/bss.c                    |   25 ++-------
 wpa_supplicant/config.c                 |    2 +
 wpa_supplicant/config.h                 |   21 +++++++
 wpa_supplicant/ctrl_iface.c             |   22 ++++++++
 wpa_supplicant/dbus/dbus_new.c          |   10 ++++
 wpa_supplicant/dbus/dbus_new_handlers.c |   88 +++++++++++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |   12 ++++
 wpa_supplicant/wpa_cli.c                |   46 ++++++++++++++++
 wpa_supplicant/wpa_supplicant.c         |   46 ++++++++++++++++
 wpa_supplicant/wpa_supplicant_i.h       |    4 ++
 10 files changed, 255 insertions(+), 21 deletions(-)

diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 145b716..1d65b2e 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -30,25 +30,6 @@
  */
 #define WPA_BSS_EXPIRATION_PERIOD 10
 
-/**
- * WPA_BSS_EXPIRATION_AGE - BSS entry age after which it can be expired
- *
- * This value control the time in seconds after which a BSS entry gets removed
- * if it has not been updated or is not in use.
- */
-#define WPA_BSS_EXPIRATION_AGE 180
-
-/**
- * WPA_BSS_EXPIRATION_SCAN_COUNT - Expire BSS after number of scans
- *
- * If the BSS entry has not been seen in this many scans, it will be removed.
- * Value 1 means that the entry is removed after the first scan without the
- * BSSID being seen. Larger values can be used to avoid BSS entries
- * disappearing if they are not visible in every scan (e.g., low signal quality
- * or interference).
- */
-#define WPA_BSS_EXPIRATION_SCAN_COUNT 2
-
 #define WPA_BSS_FREQ_CHANGED_FLAG	BIT(0)
 #define WPA_BSS_SIGNAL_CHANGED_FLAG	BIT(1)
 #define WPA_BSS_PRIVACY_CHANGED_FLAG	BIT(2)
@@ -401,10 +382,12 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
 			int new_scan)
 {
 	struct wpa_bss *bss, *n;
+	unsigned int bss_expiration_scan_count;
 
 	if (!new_scan)
 		return; /* do not expire entries without new scan */
 
+	bss_expiration_scan_count = wpa_s->conf->bss_expiration_scan_count;
 	dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
 		if (wpa_bss_in_use(wpa_s, bss))
 			continue;
@@ -412,7 +395,7 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
 			continue; /* expire only BSSes that were scanned */
 		if (bss->last_update_idx < wpa_s->bss_update_idx)
 			bss->scan_miss_count++;
-		if (bss->scan_miss_count >= WPA_BSS_EXPIRATION_SCAN_COUNT) {
+		if (bss->scan_miss_count >= bss_expiration_scan_count) {
 			wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Expire BSS %u due to "
 				"no match in scan", bss->id);
 			wpa_bss_remove(wpa_s, bss);
@@ -450,7 +433,7 @@ static void wpa_bss_timeout(void *eloop_ctx, void *timeout_ctx)
 {
 	struct wpa_supplicant *wpa_s = eloop_ctx;
 
-	wpa_bss_flush_by_age(wpa_s, WPA_BSS_EXPIRATION_AGE);
+	wpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);
 	eloop_register_timeout(WPA_BSS_EXPIRATION_PERIOD, 0,
 			       wpa_bss_timeout, wpa_s, NULL);
 }
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 24edbaf..b38529e 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2169,6 +2169,8 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
 	config->p2p_go_intent = DEFAULT_P2P_GO_INTENT;
 	config->p2p_intra_bss = DEFAULT_P2P_INTRA_BSS;
 	config->bss_max_count = DEFAULT_BSS_MAX_COUNT;
+	config->bss_expiration_age = DEFAULT_BSS_EXPIRATION_AGE;
+	config->bss_expiration_scan_count = DEFAULT_BSS_EXPIRATION_SCAN_COUNT;
 	config->max_num_sta = DEFAULT_MAX_NUM_STA;
 
 	if (ctrl_interface)
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index e2efc4b..58685e8 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -25,6 +25,8 @@
 #define DEFAULT_P2P_GO_INTENT 7
 #define DEFAULT_P2P_INTRA_BSS 1
 #define DEFAULT_BSS_MAX_COUNT 200
+#define DEFAULT_BSS_EXPIRATION_AGE 180
+#define DEFAULT_BSS_EXPIRATION_SCAN_COUNT 2
 #define DEFAULT_MAX_NUM_STA 128
 
 #include "config_ssid.h"
@@ -375,6 +377,25 @@ struct wpa_config {
 	unsigned int bss_max_count;
 
 	/**
+	 * bss_expiration_age - BSS entry age after which it can be expired
+	 *
+	 * This value controls the time in seconds after which a BSS entry
+	 * gets removed if it has not been updated or is not in use.
+	 */
+	unsigned int bss_expiration_age;
+
+	/**
+	 * bss_expiration_scan_count - Expire BSS after number of scans
+	 *
+	 * If the BSS entry has not been seen in this many scans, it will be
+	 * removed.  A value of 1 means that entry is removed after the first
+	 * scan in which the BSSID is not seen.  Larger values can be used
+	 * to avoid BSS entries disappearing if they are not visible in
+	 * every scan (e.g. low signal quality or interference).
+	 */
+	unsigned int bss_expiration_scan_count;
+
+	/**
 	 * filter_ssids - SSID-based scan result filtering
 	 *
 	 *   0 = do not filter scan results
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 9f06115..ae1cc9c 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -1994,6 +1994,22 @@ static int wpa_supplicant_ctrl_iface_ap_scan(
 }
 
 
+static int wpa_supplicant_ctrl_iface_bss_expire_age(
+	struct wpa_supplicant *wpa_s, char *cmd)
+{
+	int expire_age = atoi(cmd);
+	return wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age);
+}
+
+
+static int wpa_supplicant_ctrl_iface_bss_expire_count(
+	struct wpa_supplicant *wpa_s, char *cmd)
+{
+	int expire_count = atoi(cmd);
+	return wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count);
+}
+
+
 static void wpa_supplicant_ctrl_iface_drop_sa(struct wpa_supplicant *wpa_s)
 {
 	wpa_printf(MSG_DEBUG, "Dropping SA without deauthentication");
@@ -3194,6 +3210,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 	} else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) {
 		if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16))
 			reply_len = -1;
+	} else if (os_strncmp(buf, "BSS_EXPIRE_AGE ", 15) == 0) {
+		if (wpa_supplicant_ctrl_iface_bss_expire_age(wpa_s, buf + 15))
+			reply_len = -1;
+	} else if (os_strncmp(buf, "BSS_EXPIRE_COUNT ", 17) == 0) {
+		if (wpa_supplicant_ctrl_iface_bss_expire_count(wpa_s, buf + 17))
+			reply_len = -1;
 #ifdef CONFIG_TDLS
 	} else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) {
 		if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14))
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 63bea98..d3698f8 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -1386,6 +1386,16 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
 	  (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
 	  RW
 	},
+	{ "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
+	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_age,
+	  (WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_age,
+	  RW
+	},
+	{ "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
+	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_count,
+	  (WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_count,
+	  RW
+	},
 	{ "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
 	  (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
 	  NULL, R
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 62f5025..0994c03 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -2152,6 +2152,94 @@ DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
 
 
 /**
+ * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: A message containing value of bss_expiration_age variable
+ *
+ * Getter function for "BSSExpireAge" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_expire_age(DBusMessage *message,
+				       struct wpa_supplicant *wpa_s)
+{
+	dbus_uint32_t expire_age = wpa_s->conf->bss_expiration_age;
+	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
+						&expire_age);
+}
+
+
+/**
+ * wpas_dbus_setter_bss_expire_age - Control BSS entry expiration age
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL
+ *
+ * Setter function for "BSSExpireAge" property.
+ */
+DBusMessage * wpas_dbus_setter_bss_expire_age(DBusMessage *message,
+				       struct wpa_supplicant *wpa_s)
+{
+	DBusMessage *reply = NULL;
+	dbus_uint32_t expire_age;
+
+	reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
+						 &expire_age);
+	if (reply)
+		return reply;
+
+	if (wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age)) {
+		return wpas_dbus_error_invalid_args(
+			message, "BSSExpireAge must be >=10");
+	}
+	return NULL;
+}
+
+
+/**
+ * wpas_dbus_getter_bss_expire_count - Get BSS entry expiration scan count
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: A message containing value of bss_expire_count variable
+ *
+ * Getter function for "BSSExpireCount" property.
+ */
+DBusMessage * wpas_dbus_getter_bss_expire_count(DBusMessage *message,
+				       struct wpa_supplicant *wpa_s)
+{
+	dbus_uint32_t expire_count = wpa_s->conf->bss_expiration_age;
+	return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT32,
+						&expire_count);
+}
+
+
+/**
+ * wpas_dbus_setter_bss_expire_count - Control BSS entry expiration scan count
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL
+ *
+ * Setter function for "BSSExpireCount" property.
+ */
+DBusMessage * wpas_dbus_setter_bss_expire_count(DBusMessage *message,
+				       struct wpa_supplicant *wpa_s)
+{
+	DBusMessage *reply = NULL;
+	dbus_uint32_t expire_count;
+
+	reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_UINT32,
+						 &expire_count);
+	if (reply)
+		return reply;
+
+	if (wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count)) {
+		return wpas_dbus_error_invalid_args(
+			message, "BSSExpireCount must equal >0");
+	}
+	return NULL;
+}
+
+
+/**
  * wpas_dbus_getter_ifname - Get interface name
  * @message: Pointer to incoming dbus message
  * @wpa_s: wpa_supplicant structure for a network interface
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 03c1ea4..1cc12e8 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -116,6 +116,18 @@ DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
 DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
 				       struct wpa_supplicant *wpa_s);
 
+DBusMessage * wpas_dbus_getter_bss_expire_age(DBusMessage *message,
+				       struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_setter_bss_expire_age(DBusMessage *message,
+				       struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_getter_bss_expire_count(DBusMessage *message,
+				       struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_setter_bss_expire_count(DBusMessage *message,
+				       struct wpa_supplicant *wpa_s);
+
 DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
 				      struct wpa_supplicant *wpa_s);
 
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index f0ba628..e422402 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -475,6 +475,46 @@ static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
 }
 
 
+static int wpa_cli_cmd_bss_expire_age(struct wpa_ctrl *ctrl, int argc,
+				      char *argv[])
+{
+	char cmd[256];
+	int res;
+
+	if (argc != 1) {
+		printf("Invalid BSS_EXPIRE_AGE command: needs one argument "
+		       "(bss_expire_age value)\n");
+		return -1;
+	}
+	res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_AGE %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+		printf("Too long BSS_EXPIRE_AGE command.\n");
+		return -1;
+	}
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cli_cmd_bss_expire_count(struct wpa_ctrl *ctrl, int argc,
+				        char *argv[])
+{
+	char cmd[256];
+	int res;
+
+	if (argc != 1) {
+		printf("Invalid BSS_EXPIRE_COUNT command: needs one argument "
+		       "(bss_expire_count value)\n");
+		return -1;
+	}
+	res = os_snprintf(cmd, sizeof(cmd), "BSS_EXPIRE_COUNT %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+		printf("Too long BSS_EXPIRE_COUNT command.\n");
+		return -1;
+	}
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
 static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
 				char *argv[])
 {
@@ -2389,6 +2429,12 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
 	{ "ap_scan", wpa_cli_cmd_ap_scan,
 	  cli_cmd_flag_none,
 	  "<value> = set ap_scan parameter" },
+	{ "bss_expire_age", wpa_cli_cmd_bss_expire_age,
+	  cli_cmd_flag_none,
+	  "<value> = set BSS expiration age parameter" },
+	{ "bss_expire_count", wpa_cli_cmd_bss_expire_count,
+	  cli_cmd_flag_none,
+	  "<value> = set BSS expiration scan count parameter" },
 	{ "stkstart", wpa_cli_cmd_stkstart,
 	  cli_cmd_flag_none,
 	  "<addr> = request STK negotiation with <addr>" },
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 16cb735..d9f33b5 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1659,6 +1659,52 @@ int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
 
 
 /**
+ * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * @expire_age: expiration age in seconds
+ * Returns: 0 if succeed or -1 if expire_age has an invalid value
+ *
+ */
+int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
+					  unsigned int bss_expire_age)
+{
+	if (bss_expire_age < 10) {
+		wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
+		    bss_expire_age);
+		return -1;
+	}
+	wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
+	    bss_expire_age);
+	wpa_s->conf->bss_expiration_age = bss_expire_age;
+
+	return 0;
+}
+
+
+/**
+ * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * @expire_count: number of scans after which an unseen BSS is reclaimed
+ * Returns: 0 if succeed or -1 if expire_count has an invalid value
+ *
+ */
+int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
+					    unsigned int bss_expire_count)
+{
+	if (bss_expire_count < 1) {
+		wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
+		    bss_expire_count);
+		return -1;
+	}
+	wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
+	    bss_expire_count);
+	wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
+
+	return 0;
+}
+
+
+/**
  * wpa_supplicant_set_debug_params - Set global debug params
  * @global: wpa_global structure
  * @debug_level: debug level
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 056ffa0..a751f81 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -590,6 +590,10 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
 				   struct wpa_ssid *ssid);
 int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s,
 			       int ap_scan);
+int wpa_supplicant_set_expiration_age(struct wpa_supplicant *wpa_s,
+			       unsigned int expire_age);
+int wpa_supplicant_set_expiration_count(struct wpa_supplicant *wpa_s,
+			       unsigned int expire_count);
 int wpa_supplicant_set_debug_params(struct wpa_global *global,
 				    int debug_level, int debug_timestamp,
 				    int debug_show_keys);
-- 
1.7.3.1




More information about the Hostap mailing list