wpa_supplicant: Parameterize BSS table expiration age + count
Replace compile-time BSS cache expiration age and scan count by config parameters that can be set via wpa_cli and the new D-Bus API. The latter is done with interface properties BSSExpireAge and BSSExpireCount.
This commit is contained in:
parent
cfe53c9aa5
commit
78633c3709
11 changed files with 264 additions and 21 deletions
|
@ -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)
|
||||
|
@ -412,7 +393,8 @@ 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 >=
|
||||
wpa_s->conf->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 +432,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);
|
||||
}
|
||||
|
|
|
@ -2170,6 +2170,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)
|
||||
|
@ -2439,6 +2441,8 @@ static const struct global_parse_data global_fields[] = {
|
|||
#endif /* CONFIG_P2P */
|
||||
{ FUNC(country), CFG_CHANGED_COUNTRY },
|
||||
{ INT(bss_max_count), 0 },
|
||||
{ INT(bss_expiration_age), 0 },
|
||||
{ INT(bss_expiration_scan_count), 0 },
|
||||
{ INT_RANGE(filter_ssids, 0, 1), 0 },
|
||||
{ INT(max_num_sta), 0 },
|
||||
{ INT_RANGE(disassoc_low_ack, 0, 1), 0 }
|
||||
|
|
|
@ -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"
|
||||
|
@ -381,6 +383,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
|
||||
*
|
||||
|
|
|
@ -690,6 +690,13 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
|
|||
}
|
||||
if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT)
|
||||
fprintf(f, "bss_max_count=%u\n", config->bss_max_count);
|
||||
if (config->bss_expiration_age != DEFAULT_BSS_EXPIRATION_AGE)
|
||||
fprintf(f, "bss_expiration_age=%u\n",
|
||||
config->bss_expiration_age);
|
||||
if (config->bss_expiration_scan_count !=
|
||||
DEFAULT_BSS_EXPIRATION_SCAN_COUNT)
|
||||
fprintf(f, "bss_expiration_scan_count=%u\n",
|
||||
config->bss_expiration_scan_count);
|
||||
if (config->filter_ssids)
|
||||
fprintf(f, "filter_ssids=%d\n", config->filter_ssids);
|
||||
if (config->max_num_sta != DEFAULT_MAX_NUM_STA)
|
||||
|
|
|
@ -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,13 @@ 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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2155,6 +2155,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 be >0");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpas_dbus_getter_ifname - Get interface name
|
||||
* @message: Pointer to incoming dbus message
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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>" },
|
||||
|
|
|
@ -1661,6 +1661,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
|
||||
|
|
|
@ -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_bss_expiration_age(struct wpa_supplicant *wpa_s,
|
||||
unsigned int expire_age);
|
||||
int wpa_supplicant_set_bss_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);
|
||||
|
|
Loading…
Reference in a new issue