diff options
author | KN | 2020-06-09 16:11:29 -0500 |
---|---|---|
committer | KN | 2020-06-09 16:11:29 -0500 |
commit | f0546c5f1671bb8aea2cd8298eea50eab9f46f0f (patch) | |
tree | 9e9142da7fa50763755497291664fc87dc41f95b | |
parent | 3e8bcd5fe9f23cded9d73b3bb73fc92f699aea5a (diff) | |
download | hostap-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.h | 1 | ||||
-rw-r--r-- | wpa_supplicant/mesh.c | 14 | ||||
-rw-r--r-- | wpa_supplicant/mesh_mpm.c | 38 | ||||
-rw-r--r-- | wpa_supplicant/mesh_mpm.h | 6 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant.c | 13 |
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 | |||
725 | int 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 | ||
466 | static 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 | } | ||
466 | static void plink_timer(void *eloop_ctx, void *user_data) | 492 | static 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 | ||
533 | static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta, | 559 | int 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 | ||
631 | void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh) | 658 | void 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 */ |
13 | void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr, | 13 | void 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); |
15 | void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh); | 15 | void mesh_mpm_close_links(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh); |
16 | void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr); | 16 | void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr); |
17 | void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta); | 17 | void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta); |
18 | void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s, | 18 | void 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, | |||
21 | int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr); | 21 | int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr); |
22 | int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr, | 22 | int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr, |
23 | int duration); | 23 | int duration); |
24 | int 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); |
29 | void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt); | 31 | void 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 | ||
33 | static inline void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s, | 37 | static 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) { |