aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKN2020-06-09 16:11:29 -0500
committerKN2020-06-09 16:11:29 -0500
commitf0546c5f1671bb8aea2cd8298eea50eab9f46f0f (patch)
tree9e9142da7fa50763755497291664fc87dc41f95b
parent3e8bcd5fe9f23cded9d73b3bb73fc92f699aea5a (diff)
downloadhostap-f0546c5f1671bb8aea2cd8298eea50eab9f46f0f.tar.gz
hostap-f0546c5f1671bb8aea2cd8298eea50eab9f46f0f.tar.xz
hostap-f0546c5f1671bb8aea2cd8298eea50eab9f46f0f.zip
0030 - Mesh: bug fix - make sure when we disconnect we wait for plink_close to be received
When leaving mesh we are not waiting for the other side to respond to our close command and tear down the interface. This fix waits for 300ms and only then tears down the interface leaving enough time for the other side to receive our close action and send us a close action back. note - there is still an issue with mesh_join - when calling mesh join we first tear down the last mesh - in that case we won't wait - and this bug still occurs - needs to be fixed later on. Signed-off-by: KN <sudharshan@ti.com>
-rw-r--r--src/ap/hostapd.h1
-rw-r--r--wpa_supplicant/mesh.c14
-rw-r--r--wpa_supplicant/mesh_mpm.c38
-rw-r--r--wpa_supplicant/mesh_mpm.h6
-rw-r--r--wpa_supplicant/wpa_supplicant.c13
5 files changed, 58 insertions, 14 deletions
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 518c7f10b..084ad3a46 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -433,6 +433,7 @@ struct hostapd_iface {
433 433
434#ifdef CONFIG_MESH 434#ifdef CONFIG_MESH
435 struct mesh_conf *mconf; 435 struct mesh_conf *mconf;
436 Boolean mesh_deinit_process;
436#endif /* CONFIG_MESH */ 437#endif /* CONFIG_MESH */
437 438
438 size_t num_bss; 439 size_t num_bss;
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index fb72ed869..8b16ef264 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -48,7 +48,8 @@ void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
48 return; 48 return;
49 49
50 if (ifmsh->mconf) { 50 if (ifmsh->mconf) {
51 mesh_mpm_deinit(wpa_s, ifmsh); 51 struct hostapd_data *hapd = ifmsh->bss[0];
52 hostapd_free_stas(hapd);
52 if (ifmsh->mconf->rsn_ie) { 53 if (ifmsh->mconf->rsn_ie) {
53 ifmsh->mconf->rsn_ie = NULL; 54 ifmsh->mconf->rsn_ie = NULL;
54 /* We cannot free this struct 55 /* We cannot free this struct
@@ -265,6 +266,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
265 if (!ifmsh) 266 if (!ifmsh)
266 return -ENOMEM; 267 return -ENOMEM;
267 268
269 ifmsh->mesh_deinit_process = FALSE;
268 ifmsh->drv_flags = wpa_s->drv_flags; 270 ifmsh->drv_flags = wpa_s->drv_flags;
269 ifmsh->num_bss = 1; 271 ifmsh->num_bss = 1;
270 ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss, 272 ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
@@ -450,6 +452,9 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
450 goto out; 452 goto out;
451 } 453 }
452 454
455 if (wpa_s->ifmsh)
456 mesh_mpm_close_links(wpa_s,wpa_s->ifmsh);
457
453 wpa_supplicant_mesh_deinit(wpa_s); 458 wpa_supplicant_mesh_deinit(wpa_s);
454 459
455 wpa_s->pairwise_cipher = WPA_CIPHER_NONE; 460 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
@@ -715,3 +720,10 @@ int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
715{ 720{
716 return mesh_mpm_connect_peer(wpa_s, addr, duration); 721 return mesh_mpm_connect_peer(wpa_s, addr, duration);
717} 722}
723
724
725int wpa_supplicant_leave_mesh_initiate(struct wpa_supplicant *wpa_s)
726{
727 wpa_s->ifmsh->mesh_deinit_process = TRUE;
728 mesh_mpm_close_links(wpa_s,wpa_s->ifmsh);
729}
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index c2c498138..8e1d016f1 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -463,6 +463,32 @@ static void mesh_mpm_fsm_restart(struct wpa_supplicant *wpa_s,
463} 463}
464 464
465 465
466static void mesh_close_links_timer(void *eloop_ctx, void *user_data)
467{
468 struct wpa_supplicant *wpa_s = eloop_ctx;
469 struct hostapd_data *hapd = NULL;
470
471 if (wpa_s->ifmsh)
472 hapd = wpa_s->ifmsh->bss[0];
473
474 /*
475 *in case we timed out and not all mesh links were closed appropriately
476 * we now clean all links
477 */
478
479 if (hapd) {
480 while (hapd->num_plinks > 0) {
481 wpa_msg(wpa_s, MSG_ERROR,"mesh_close_links_timer, num of plinks: %d",hapd->num_plinks );
482
483 hapd->num_plinks--;
484 mesh_mpm_fsm_restart(wpa_s, hapd->sta_list);
485 }
486 }
487
488 if ( (wpa_s->ifmsh) && (wpa_s->ifmsh->mesh_deinit_process) )
489 wpa_supplicant_leave_mesh(wpa_s);
490
491}
466static void plink_timer(void *eloop_ctx, void *user_data) 492static void plink_timer(void *eloop_ctx, void *user_data)
467{ 493{
468 struct wpa_supplicant *wpa_s = eloop_ctx; 494 struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -530,7 +556,7 @@ mesh_mpm_plink_open(struct wpa_supplicant *wpa_s, struct sta_info *sta,
530} 556}
531 557
532 558
533static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta, 559int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
534 void *ctx) 560 void *ctx)
535{ 561{
536 struct wpa_supplicant *wpa_s = ctx; 562 struct wpa_supplicant *wpa_s = ctx;
@@ -538,6 +564,7 @@ static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
538 564
539 if (sta) { 565 if (sta) {
540 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING); 566 wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
567 hapd->num_plinks--;
541 mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason); 568 mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
542 wpa_printf(MSG_DEBUG, "MPM closing plink sta=" MACSTR, 569 wpa_printf(MSG_DEBUG, "MPM closing plink sta=" MACSTR,
543 MAC2STR(sta->addr)); 570 MAC2STR(sta->addr));
@@ -628,16 +655,14 @@ int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
628} 655}
629 656
630 657
631void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh) 658void mesh_mpm_close_links(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh)
632{ 659{
633 struct hostapd_data *hapd = ifmsh->bss[0]; 660 struct hostapd_data *hapd = ifmsh->bss[0];
634 661
635 /* notify peers we're leaving */ 662 /* notify peers we're leaving */
636 ap_for_each_sta(hapd, mesh_mpm_plink_close, wpa_s); 663 ap_for_each_sta(hapd, mesh_mpm_plink_close, wpa_s);
637 664
638 hapd->num_plinks = 0; 665 eloop_register_timeout(0, MESH_CLOSE_LINKS_RESPONSE_TIMER, mesh_close_links_timer, wpa_s, NULL);
639 hostapd_free_stas(hapd);
640 eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
641} 666}
642 667
643 668
@@ -807,6 +832,9 @@ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
807 struct ieee80211_mesh_config *mesh_conf_ie = 832 struct ieee80211_mesh_config *mesh_conf_ie =
808 (struct ieee80211_mesh_config *)elems->mesh_config; 833 (struct ieee80211_mesh_config *)elems->mesh_config;
809 834
835 if (wpa_s->ifmsh->mesh_deinit_process)
836 return;
837
810 /* check if peer accepts new connection. Don't initiate link if peer is full*/ 838 /* check if peer accepts new connection. Don't initiate link if peer is full*/
811 if ((ssid && ssid->no_auto_peer && 839 if ((ssid && ssid->no_auto_peer &&
812 (is_zero_ether_addr(data->mesh_required_peer) || 840 (is_zero_ether_addr(data->mesh_required_peer) ||
diff --git a/wpa_supplicant/mesh_mpm.h b/wpa_supplicant/mesh_mpm.h
index 5fc1e6184..26111f22c 100644
--- a/wpa_supplicant/mesh_mpm.h
+++ b/wpa_supplicant/mesh_mpm.h
@@ -12,7 +12,7 @@
12/* notify MPM of new mesh peer to be inserted in MPM and driver */ 12/* notify MPM of new mesh peer to be inserted in MPM and driver */
13void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr, 13void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
14 struct ieee802_11_elems *elems); 14 struct ieee802_11_elems *elems);
15void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh); 15void mesh_mpm_close_links(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh);
16void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr); 16void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
17void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta); 17void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
18void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s, 18void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
@@ -21,6 +21,8 @@ void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
21int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr); 21int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
22int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr, 22int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
23 int duration); 23 int duration);
24int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
25 void *ctx);
24 26
25#ifdef CONFIG_MESH 27#ifdef CONFIG_MESH
26 28
@@ -28,6 +30,8 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
28 const struct ieee80211_mgmt *mgmt, size_t len); 30 const struct ieee80211_mgmt *mgmt, size_t len);
29void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt); 31void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt);
30 32
33#define MESH_CLOSE_LINKS_RESPONSE_TIMER 300000 // 300 ms - 300,000usec
34
31#else /* CONFIG_MESH */ 35#else /* CONFIG_MESH */
32 36
33static inline void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s, 37static inline void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 4a0edc74c..63724a619 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3484,11 +3484,12 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
3484 struct mesh_conf *mconf; 3484 struct mesh_conf *mconf;
3485 3485
3486 mconf = wpa_s->ifmsh->mconf; 3486 mconf = wpa_s->ifmsh->mconf;
3487 wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
3488 wpa_s->ifname);
3489 wpas_notify_mesh_group_removed(wpa_s, mconf->meshid, 3487 wpas_notify_mesh_group_removed(wpa_s, mconf->meshid,
3490 mconf->meshid_len, reason_code); 3488 mconf->meshid_len, reason_code);
3491 wpa_supplicant_leave_mesh(wpa_s); 3489 wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
3490 wpa_s->ifname);
3491 wpa_supplicant_leave_mesh_initiate(wpa_s);
3492
3492 } 3493 }
3493#endif /* CONFIG_MESH */ 3494#endif /* CONFIG_MESH */
3494 3495
@@ -6050,10 +6051,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
6050 } 6051 }
6051 6052
6052#ifdef CONFIG_MESH 6053#ifdef CONFIG_MESH
6053 if (wpa_s->ifmsh) { 6054 if (wpa_s->ifmsh)
6054 wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh); 6055 wpa_supplicant_leave_mesh(wpa_s);
6055 wpa_s->ifmsh = NULL;
6056 }
6057#endif /* CONFIG_MESH */ 6056#endif /* CONFIG_MESH */
6058 6057
6059 if (wpa_s->conf != NULL) { 6058 if (wpa_s->conf != NULL) {