Toggle to flush BSS entries when interface is disabled

Message ID CADZiLaaX9Zhrf9aWGSCvsuOMjv+gSo+dgkxa51+fLvNNitNBGQ@mail.gmail.com
State New
Headers show
Series
  • Toggle to flush BSS entries when interface is disabled
Related show

Commit Message

Jong Wook Kim March 6, 2018, 1:01 a.m.
Currently, bss entries are cleared out whenever the interface goes down.
This is the right thing to do most of the time, but this flush is unnecessary
when we are intentionally bringing the interface down and up as it takes
~3 seconds to re-scan all channels and fill up the bss entries again.

For Connected MAC Randomization, we have to bring the interface down,
change MAC address, bring the interface back up, and then start associating
(and we are observing ~3 scan delay here due to re-scanning).
Thus, we would like to have an option to not flush the cache when the
interface is disabled.

Do let me know if there would be a better way to avoid this delay. Thanks.

Signed-off-by: Jong Wook Kim <jongwook@google.com>
---
 wpa_supplicant/config.c      | 1 +
 wpa_supplicant/config.h      | 8 ++++++++
 wpa_supplicant/config_file.c | 3 +++
 wpa_supplicant/events.c      | 4 +++-
 4 files changed, 15 insertions(+), 1 deletion(-)

  wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);

Comments

Dan Williams March 6, 2018, 3:31 a.m. | #1
On Mon, 2018-03-05 at 17:01 -0800, Jong Wook Kim wrote:
> Currently, bss entries are cleared out whenever the interface goes
> down.
> This is the right thing to do most of the time, but this flush is
> unnecessary
> when we are intentionally bringing the interface down and up as it
> takes
> ~3 seconds to re-scan all channels and fill up the bss entries again.
> 
> For Connected MAC Randomization, we have to bring the interface down,
> change MAC address, bring the interface back up, and then start
> associating
> (and we are observing ~3 scan delay here due to re-scanning).
> Thus, we would like to have an option to not flush the cache when the
> interface is disabled.
> 
> Do let me know if there would be a better way to avoid this delay.
> Thanks.

Possibly a cleaner option would be to add a "change this interface's
MAC address to X" control interface call to the supplicant that takes
an optional parameter that says whether or not to flush BSSes.  (not
quite sure how it would suppress the netlink events that would just end
up back in wpa_supplicant_event though).

The toggle in the patch below is a pretty big hammer, since it will
happen for every EVENT_INTERFACE_DISABLED, whether that's intended or
not.  There are clearly cases where it would be useful to flush the BSS
list on interface down.

Dan

> Signed-off-by: Jong Wook Kim <jongwook@google.com>
> ---
>  wpa_supplicant/config.c      | 1 +
>  wpa_supplicant/config.h      | 8 ++++++++
>  wpa_supplicant/config_file.c | 3 +++
>  wpa_supplicant/events.c      | 4 +++-
>  4 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
> index a22434cb..87161481 100644
> --- a/wpa_supplicant/config.c
> +++ b/wpa_supplicant/config.c
> @@ -4642,6 +4642,7 @@ static const struct global_parse_data
> global_fields[] = {
>   { INT(gas_rand_addr_lifetime), 0 },
>   { INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
>   { INT_RANGE(dpp_config_processing, 0, 2), 0 },
> + { INT_RANGE(bss_no_flush_when_down, 0, 1), 0 },
>  };
> 
>  #undef FUNC
> diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
> index 07b67e6b..c63ef1d6 100644
> --- a/wpa_supplicant/config.h
> +++ b/wpa_supplicant/config.h
> @@ -1418,6 +1418,14 @@ struct wpa_config {
>   * profile automatically
>   */
>   int dpp_config_processing;
> +
> + /**
> + * bss_no_flush_when_down - Whether to flush BSS entries when the
> interface is disabled
> + *
> + * 0 = Flush BSS entries when the interface becomes disabled
> (Default)
> + * 1 = Do not flush BSS entries when the interface becomes disabled
> + */
> + int bss_no_flush_when_down;
>  };
> 
> 
> diff --git a/wpa_supplicant/config_file.c
> b/wpa_supplicant/config_file.c
> index 1fd432d1..d219c3da 100644
> --- a/wpa_supplicant/config_file.c
> +++ b/wpa_supplicant/config_file.c
> @@ -1490,6 +1490,9 @@ static void wpa_config_write_global(FILE *f,
> struct wpa_config *config)
>   if (config->dpp_config_processing)
>   fprintf(f, "dpp_config_processing=%d\n",
>   config->dpp_config_processing);
> + if (config->bss_no_flush_when_down)
> + fprintf(f, "bss_no_flush_when_down=%d\n",
> + config->bss_no_flush_when_down);
> 
>  }
> 
> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> index 63cf7737..708c6fc3 100644
> --- a/wpa_supplicant/events.c
> +++ b/wpa_supplicant/events.c
> @@ -4390,7 +4390,9 @@ void wpa_supplicant_event(void *ctx, enum
> wpa_event_type event,
>   wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
>   }
>   wpa_supplicant_mark_disassoc(wpa_s);
> - wpa_bss_flush(wpa_s);
> + if (wpa_s->conf->bss_no_flush_when_down == 0)
> + wpa_bss_flush(wpa_s);
> +
>   radio_remove_works(wpa_s, NULL, 0);
> 
>   wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
> _______________________________________________
> Hostap mailing list
> Hostap@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap
Jong Wook Kim March 7, 2018, 1:08 a.m. | #2
That is a good point as in most cases, we do want BSS entries flushed.

We found this driver_nl80211->ignore_if_down_event value
that if set, prevents EVENT_INTERFACE_DISABLED from being
sent out when the interface goes down (as a result, there would be no
BSS flush when down). This is currently used when we are changing
the driver mode.

We are thinking about simply setting this value before bringing the interface
down for MAC change. Do you have any feedback for doing things this way?

Thanks.

Jong

On Mon, Mar 5, 2018 at 7:31 PM, Dan Williams <dcbw@redhat.com> wrote:
> On Mon, 2018-03-05 at 17:01 -0800, Jong Wook Kim wrote:
>> Currently, bss entries are cleared out whenever the interface goes
>> down.
>> This is the right thing to do most of the time, but this flush is
>> unnecessary
>> when we are intentionally bringing the interface down and up as it
>> takes
>> ~3 seconds to re-scan all channels and fill up the bss entries again.
>>
>> For Connected MAC Randomization, we have to bring the interface down,
>> change MAC address, bring the interface back up, and then start
>> associating
>> (and we are observing ~3 scan delay here due to re-scanning).
>> Thus, we would like to have an option to not flush the cache when the
>> interface is disabled.
>>
>> Do let me know if there would be a better way to avoid this delay.
>> Thanks.
>
> Possibly a cleaner option would be to add a "change this interface's
> MAC address to X" control interface call to the supplicant that takes
> an optional parameter that says whether or not to flush BSSes.  (not
> quite sure how it would suppress the netlink events that would just end
> up back in wpa_supplicant_event though).
>
> The toggle in the patch below is a pretty big hammer, since it will
> happen for every EVENT_INTERFACE_DISABLED, whether that's intended or
> not.  There are clearly cases where it would be useful to flush the BSS
> list on interface down.
>
> Dan
>
>> Signed-off-by: Jong Wook Kim <jongwook@google.com>
>> ---
>>  wpa_supplicant/config.c      | 1 +
>>  wpa_supplicant/config.h      | 8 ++++++++
>>  wpa_supplicant/config_file.c | 3 +++
>>  wpa_supplicant/events.c      | 4 +++-
>>  4 files changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
>> index a22434cb..87161481 100644
>> --- a/wpa_supplicant/config.c
>> +++ b/wpa_supplicant/config.c
>> @@ -4642,6 +4642,7 @@ static const struct global_parse_data
>> global_fields[] = {
>>   { INT(gas_rand_addr_lifetime), 0 },
>>   { INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
>>   { INT_RANGE(dpp_config_processing, 0, 2), 0 },
>> + { INT_RANGE(bss_no_flush_when_down, 0, 1), 0 },
>>  };
>>
>>  #undef FUNC
>> diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
>> index 07b67e6b..c63ef1d6 100644
>> --- a/wpa_supplicant/config.h
>> +++ b/wpa_supplicant/config.h
>> @@ -1418,6 +1418,14 @@ struct wpa_config {
>>   * profile automatically
>>   */
>>   int dpp_config_processing;
>> +
>> + /**
>> + * bss_no_flush_when_down - Whether to flush BSS entries when the
>> interface is disabled
>> + *
>> + * 0 = Flush BSS entries when the interface becomes disabled
>> (Default)
>> + * 1 = Do not flush BSS entries when the interface becomes disabled
>> + */
>> + int bss_no_flush_when_down;
>>  };
>>
>>
>> diff --git a/wpa_supplicant/config_file.c
>> b/wpa_supplicant/config_file.c
>> index 1fd432d1..d219c3da 100644
>> --- a/wpa_supplicant/config_file.c
>> +++ b/wpa_supplicant/config_file.c
>> @@ -1490,6 +1490,9 @@ static void wpa_config_write_global(FILE *f,
>> struct wpa_config *config)
>>   if (config->dpp_config_processing)
>>   fprintf(f, "dpp_config_processing=%d\n",
>>   config->dpp_config_processing);
>> + if (config->bss_no_flush_when_down)
>> + fprintf(f, "bss_no_flush_when_down=%d\n",
>> + config->bss_no_flush_when_down);
>>
>>  }
>>
>> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
>> index 63cf7737..708c6fc3 100644
>> --- a/wpa_supplicant/events.c
>> +++ b/wpa_supplicant/events.c
>> @@ -4390,7 +4390,9 @@ void wpa_supplicant_event(void *ctx, enum
>> wpa_event_type event,
>>   wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
>>   }
>>   wpa_supplicant_mark_disassoc(wpa_s);
>> - wpa_bss_flush(wpa_s);
>> + if (wpa_s->conf->bss_no_flush_when_down == 0)
>> + wpa_bss_flush(wpa_s);
>> +
>>   radio_remove_works(wpa_s, NULL, 0);
>>
>>   wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
>> _______________________________________________
>> Hostap mailing list
>> Hostap@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/hostap

Patch

From 127153e35d70f82d0d00e77063c1d35212caf249 Mon Sep 17 00:00:00 2001
From: Jong Wook Kim <jongwook@google.com>
Date: Thu, 15 Feb 2018 12:23:44 -0800
Subject: [PATCH] Toggle to flush BSS entries when interface is disabled

Add bss_no_flush_when_down toggle to decide whether to delete BSS entries
when the interface is disabled. In default case, we want to flush the
BSS entries as the data will become stale. However, when we are manually
bringing the interface down and up (for Connected MAC Randomization), we
want to keep the data to prevent scanning the channels again and waste
~3 seconds.

Bug: 73301881
Test: Manual check that cache is not flushed with toggle on
Change-Id: I4caef6792789e351e649e6fd2dca61e867df2b1a
---
 wpa_supplicant/config.c      | 1 +
 wpa_supplicant/config.h      | 8 ++++++++
 wpa_supplicant/config_file.c | 3 +++
 wpa_supplicant/events.c      | 4 +++-
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index a22434cb..87161481 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -4642,6 +4642,7 @@  static const struct global_parse_data global_fields[] = {
 	{ INT(gas_rand_addr_lifetime), 0 },
 	{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
 	{ INT_RANGE(dpp_config_processing, 0, 2), 0 },
+	{ INT_RANGE(bss_no_flush_when_down, 0, 1), 0 },
 };
 
 #undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 07b67e6b..c63ef1d6 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1418,6 +1418,14 @@  struct wpa_config {
 	 *	profile automatically
 	 */
 	int dpp_config_processing;
+
+	/**
+	 * bss_no_flush_when_down - Whether to flush BSS entries when the interface is disabled
+	 *
+	 * 0 = Flush BSS entries when the interface becomes disabled (Default)
+	 * 1 = Do not flush BSS entries when the interface becomes disabled
+	 */
+	int bss_no_flush_when_down;
 };
 
 
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 1fd432d1..d219c3da 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1490,6 +1490,9 @@  static void wpa_config_write_global(FILE *f, struct wpa_config *config)
 	if (config->dpp_config_processing)
 		fprintf(f, "dpp_config_processing=%d\n",
 			config->dpp_config_processing);
+	if (config->bss_no_flush_when_down)
+		fprintf(f, "bss_no_flush_when_down=%d\n",
+			config->bss_no_flush_when_down);
 
 }
 
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 63cf7737..708c6fc3 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -4390,7 +4390,9 @@  void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 				wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
 		}
 		wpa_supplicant_mark_disassoc(wpa_s);
-		wpa_bss_flush(wpa_s);
+		if (wpa_s->conf->bss_no_flush_when_down == 0)
+			wpa_bss_flush(wpa_s);
+
 		radio_remove_works(wpa_s, NULL, 0);
 
 		wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
-- 
2.16.2.395.g2e18187dfd-goog