aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2014-10-20 09:40:29 (GMT)
committerJouni Malinen <j@w1.fi>2014-10-21 14:35:15 (GMT)
commit26fc96e89b9f0ecd16e1ecbdc41a375b2cc752a7 (patch)
treec7847726dcafcc9f50f5850da5f36cdfbce28d2f
parenteb92d389a8c3c5d84b4af2513f6e5908ecdec1e5 (diff)
downloadhostap-26fc96e89b9f0ecd16e1ecbdc41a375b2cc752a7.zip
hostap-26fc96e89b9f0ecd16e1ecbdc41a375b2cc752a7.tar.gz
hostap-26fc96e89b9f0ecd16e1ecbdc41a375b2cc752a7.tar.bz2
P2P: Remove all child interfaces when removing the parent
This is needed to allow dynamic removal of an interface that adds the P2P Device interface without leaving behind the management interface with invalid wpa_s->parent pointer. Signed-off-by: Jouni Malinen <j@w1.fi>
-rw-r--r--wpa_supplicant/p2p_supplicant.c2
-rw-r--r--wpa_supplicant/p2p_supplicant.h8
-rw-r--r--wpa_supplicant/wpa_supplicant.c20
3 files changed, 27 insertions, 3 deletions
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index b4cef9e..d0e9e05 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -7981,8 +7981,6 @@ void wpas_p2p_indicate_state_change(struct wpa_supplicant *wpa_s)
void wpas_p2p_deinit_iface(struct wpa_supplicant *wpa_s)
{
- if (wpa_s == wpa_s->parent)
- wpas_p2p_group_remove(wpa_s, "*");
if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
"the management interface is being removed");
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index b61d57f..4bc90fb 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -29,7 +29,6 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
int pd, int ht40, int vht);
int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
int freq, struct wpa_ssid *ssid);
-int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname);
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
int freq, int ht40, int vht);
int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
@@ -170,6 +169,7 @@ int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s);
int wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s);
void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail);
+int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname);
#else /* CONFIG_P2P */
@@ -293,6 +293,12 @@ static inline void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
{
}
+static inline int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s,
+ const char *ifname)
+{
+ return 0;
+}
+
#endif /* CONFIG_P2P */
#endif /* P2P_SUPPLICANT_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index b05eb86..4ada8ce 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3905,6 +3905,26 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
int notify, int terminate)
{
+ struct wpa_global *global = wpa_s->global;
+ struct wpa_supplicant *iface, *prev;
+
+ if (wpa_s == wpa_s->parent)
+ wpas_p2p_group_remove(wpa_s, "*");
+
+ iface = global->ifaces;
+ while (iface) {
+ if (iface == wpa_s || iface->parent != wpa_s) {
+ iface = iface->next;
+ continue;
+ }
+ wpa_printf(MSG_DEBUG,
+ "Remove remaining child interface %s from parent %s",
+ iface->ifname, wpa_s->ifname);
+ prev = iface;
+ iface = iface->next;
+ wpa_supplicant_remove_iface(global, prev, terminate);
+ }
+
wpa_s->disconnected = 1;
if (wpa_s->drv_priv) {
wpa_supplicant_deauthenticate(wpa_s,