mesh: Fix for mesh init/deinit

Send mesh group started notification after join completion
callback is called.

Implement outstanding TODO, to leave the mesh network on deinit.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
This commit is contained in:
Markus Theil 2020-06-30 14:19:02 +02:00 committed by Jouni Malinen
parent 06161d4f10
commit 0896c442dc
3 changed files with 26 additions and 20 deletions

View file

@ -30,20 +30,20 @@
static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s) static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s)
{ {
wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh); wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh, true);
wpa_s->ifmsh = NULL; wpa_s->ifmsh = NULL;
wpa_s->current_ssid = NULL; wpa_s->current_ssid = NULL;
os_free(wpa_s->mesh_rsn); os_free(wpa_s->mesh_rsn);
wpa_s->mesh_rsn = NULL; wpa_s->mesh_rsn = NULL;
os_free(wpa_s->mesh_params); os_free(wpa_s->mesh_params);
wpa_s->mesh_params = NULL; wpa_s->mesh_params = NULL;
/* TODO: leave mesh (stop beacon). This will happen on link down wpa_supplicant_leave_mesh(wpa_s, false);
* anyway, so it's not urgent */
} }
void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s, void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
struct hostapd_iface *ifmsh) struct hostapd_iface *ifmsh,
bool also_clear_hostapd)
{ {
if (!ifmsh) if (!ifmsh)
return; return;
@ -64,9 +64,11 @@ void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
} }
/* take care of shared data */ /* take care of shared data */
if (also_clear_hostapd) {
hostapd_interface_deinit(ifmsh); hostapd_interface_deinit(ifmsh);
hostapd_interface_free(ifmsh); hostapd_interface_free(ifmsh);
} }
}
static struct mesh_conf * mesh_config_create(struct wpa_supplicant *wpa_s, static struct mesh_conf * mesh_config_create(struct wpa_supplicant *wpa_s,
@ -249,8 +251,7 @@ static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
wpas_mesh_init_rsn(wpa_s)) { wpas_mesh_init_rsn(wpa_s)) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
"mesh: RSN initialization failed - deinit mesh"); "mesh: RSN initialization failed - deinit mesh");
wpa_supplicant_mesh_deinit(wpa_s); wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh, false);
wpa_drv_leave_mesh(wpa_s);
return -1; return -1;
} }
@ -275,9 +276,15 @@ static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
/* hostapd sets the interface down until we associate */ /* hostapd sets the interface down until we associate */
wpa_drv_set_operstate(wpa_s, 1); wpa_drv_set_operstate(wpa_s, 1);
if (!ret) if (!ret) {
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
ssid->id);
wpas_notify_mesh_group_started(wpa_s, ssid);
}
return ret; return ret;
} }
@ -571,7 +578,7 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
wpa_s->mesh_params = params; wpa_s->mesh_params = params;
if (wpa_supplicant_mesh_init(wpa_s, ssid, &params->freq)) { if (wpa_supplicant_mesh_init(wpa_s, ssid, &params->freq)) {
wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh"); wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
wpa_drv_leave_mesh(wpa_s); wpa_supplicant_leave_mesh(wpa_s, true);
ret = -1; ret = -1;
goto out; goto out;
} }
@ -581,13 +588,14 @@ out:
} }
int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s) int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s, bool need_deinit)
{ {
int ret = 0; int ret = 0;
wpa_msg(wpa_s, MSG_INFO, "leaving mesh"); wpa_msg(wpa_s, MSG_INFO, "leaving mesh");
/* Need to send peering close messages first */ /* Need to send peering close messages first */
if (need_deinit)
wpa_supplicant_mesh_deinit(wpa_s); wpa_supplicant_mesh_deinit(wpa_s);
ret = wpa_drv_leave_mesh(wpa_s); ret = wpa_drv_leave_mesh(wpa_s);

View file

@ -11,9 +11,11 @@
int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid); struct wpa_ssid *ssid);
int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s); int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s,
bool need_deinit);
void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s, void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
struct hostapd_iface *ifmsh); struct hostapd_iface *ifmsh,
bool also_clear_hostapd);
int wpas_mesh_scan_result_text(const u8 *ies, size_t ies_len, char *buf, int wpas_mesh_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
char *end); char *end);
int wpas_mesh_add_interface(struct wpa_supplicant *wpa_s, char *ifname, int wpas_mesh_add_interface(struct wpa_supplicant *wpa_s, char *ifname,

View file

@ -2249,10 +2249,6 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
return; return;
} }
wpa_s->current_bss = bss; wpa_s->current_bss = bss;
wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
ssid->id);
wpas_notify_mesh_group_started(wpa_s, ssid);
#else /* CONFIG_MESH */ #else /* CONFIG_MESH */
wpa_msg(wpa_s, MSG_ERROR, wpa_msg(wpa_s, MSG_ERROR,
"mesh mode support not included in the build"); "mesh mode support not included in the build");
@ -3990,7 +3986,7 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
wpa_s->ifname); wpa_s->ifname);
wpas_notify_mesh_group_removed(wpa_s, mconf->meshid, wpas_notify_mesh_group_removed(wpa_s, mconf->meshid,
mconf->meshid_len, reason_code); mconf->meshid_len, reason_code);
wpa_supplicant_leave_mesh(wpa_s); wpa_supplicant_leave_mesh(wpa_s, true);
} }
#endif /* CONFIG_MESH */ #endif /* CONFIG_MESH */
@ -6717,7 +6713,7 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_MESH #ifdef CONFIG_MESH
if (wpa_s->ifmsh) { if (wpa_s->ifmsh) {
wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh); wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh, true);
wpa_s->ifmsh = NULL; wpa_s->ifmsh = NULL;
} }
#endif /* CONFIG_MESH */ #endif /* CONFIG_MESH */