[PATCH 09/18] wpa_supplicant: Always propagate scan results to all interfaces

andrei.otcheretianski at intel.com andrei.otcheretianski at intel.com
Mon Sep 5 07:33:02 PDT 2016


From: Avraham Stern <avraham.stern at intel.com>

Scan results are not propogated to all interfaces if scan results
started a new operation, in order to prevent concurrent operations.
But this causes other interfaces to trigger a new scan when scan
results are already available.
Instead, always notify other interfaces of the scan results, but note
that new operations are not allowed.

Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
 wpa_supplicant/events.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 779a423..1bb646d 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1467,11 +1467,17 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
 }
 
 
-/* Return != 0 if no scan results could be fetched or if scan results should not
- * be shared with other virtual interfaces. */
+/*
+ * Return a negative value if no scan results could be fetched or if scan
+ * Return 0 if scan results were fetched and may be shared with other interfaces.
+ * results should not be shared with other virtual interfaces.
+ * Return 1 if scan results may be shared with other virtual interfaces but may not
+ * trigger any operations.
+ * Return 2 if the interface was removed and cannot no be used.
+ */
 static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 					      union wpa_event_data *data,
-					      int own_request)
+					      int own_request, int update_only)
 {
 	struct wpa_scan_results *scan_res = NULL;
 	int ret = 0;
@@ -1521,6 +1527,17 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 	}
 #endif /* CONFIG_NO_RANDOM_POOL */
 
+	if (update_only) {
+		/*
+		 * When updating scan results from another interface's scan and
+		 * new operations are not allowed, don't cancel this interface
+		 * scan work because it may be needed to trigger some operations
+		 * on this interface.
+		 */
+		wpa_scan_results_free(scan_res);
+		return 1;
+	}
+
 	if (own_request && wpa_s->scan_res_handler &&
 	    !(data && data->scan_info.external_scan)) {
 		void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
@@ -1529,7 +1546,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 		scan_res_handler = wpa_s->scan_res_handler;
 		wpa_s->scan_res_handler = NULL;
 		scan_res_handler(wpa_s, scan_res);
-		ret = -2;
+		ret = 1;
 		goto scan_work_done;
 	}
 
@@ -1750,7 +1767,7 @@ static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 	struct wpa_supplicant *ifs;
 	int res;
 
-	res = _wpa_supplicant_event_scan_results(wpa_s, data, 1);
+	res = _wpa_supplicant_event_scan_results(wpa_s, data, 1, 0);
 	if (res == 2) {
 		/*
 		 * Interface may have been removed, so must not dereference
@@ -1758,7 +1775,8 @@ static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 		 */
 		return 1;
 	}
-	if (res != 0) {
+
+	if (res < 0) {
 		/*
 		 * If no scan results could be fetched, then no need to
 		 * notify those interfaces that did not actually request
@@ -1778,7 +1796,8 @@ static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 		if (ifs != wpa_s) {
 			wpa_printf(MSG_DEBUG, "%s: Updating scan results from "
 				   "sibling", ifs->ifname);
-			_wpa_supplicant_event_scan_results(ifs, data, 0);
+			_wpa_supplicant_event_scan_results(ifs, data, 0,
+							   res > 0 ? 1 : 0);
 		}
 	}
 
-- 
1.9.1




More information about the Hostap mailing list