diff mbox

[1/7] TDLS: handle unreachable link teardown for external setup

Message ID 1402424350-19261-1-git-send-email-ilan.peer@intel.com
State Accepted
Headers show

Commit Message

Peer, Ilan June 10, 2014, 6:19 p.m. UTC
From: Arik Nemtsov <arik@wizery.com>

If a link is unreachable, the specification mandates we should send a
teardown packet via the AP with a specific teardown reason. Force this
by first disabling the link and only then sending the teardown packet
for the LOW_ACK event.
Rename the TDLS LOW_ACK event handler to better reflect its purpose.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
---
 src/rsn_supp/tdls.c     |   21 +++++++++++++++++++--
 src/rsn_supp/wpa.h      |    2 +-
 wpa_supplicant/events.c |    3 ++-
 3 files changed, 22 insertions(+), 4 deletions(-)

Comments

Jouni Malinen June 16, 2014, 9:09 p.m. UTC | #1
Thanks, applied 1, 2, 5; dropped 3 per request; waiting for more info to
clarify commit messages and comments for 4, 6, 7.
diff mbox

Patch

diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 84b7c1b..c08d2f9 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -802,7 +802,7 @@  static void wpa_tdls_disable_peer_link(struct wpa_sm *sm,
 }
 
 
-void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr)
+void wpa_tdls_disable_unreachable_link(struct wpa_sm *sm, const u8 *addr)
 {
 	struct wpa_tdls_peer *peer;
 
@@ -811,8 +811,25 @@  void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr)
 			break;
 	}
 
-	if (peer)
+	if (!peer || !peer->tpk_success) {
+		wpa_printf(MSG_DEBUG, "TDLS: Peer " MACSTR
+		   " not connected - cannot teardown unreachable link",
+		   MAC2STR(addr));
+		return;
+	}
+
+	if (wpa_tdls_is_external_setup(sm)) {
+		/*
+		 * disable the link, send a teardown packet through the
+		 * AP, and then reset link data
+		 */
+		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, addr);
+		wpa_tdls_send_teardown(sm, addr,
+				       WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE);
+		wpa_tdls_peer_free(sm, peer);
+	} else {
 		wpa_tdls_disable_peer_link(sm, peer);
+	}
 }
 
 
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index e98967c..07a7bf9 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -385,7 +385,7 @@  int wpa_tdls_init(struct wpa_sm *sm);
 void wpa_tdls_teardown_peers(struct wpa_sm *sm);
 void wpa_tdls_deinit(struct wpa_sm *sm);
 void wpa_tdls_enable(struct wpa_sm *sm, int enabled);
-void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr);
+void wpa_tdls_disable_unreachable_link(struct wpa_sm *sm, const u8 *addr);
 const char * wpa_tdls_get_link_status(struct wpa_sm *sm, const u8 *addr);
 int wpa_tdls_is_external_setup(struct wpa_sm *sm);
 
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 6551f93..8777661 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -3414,7 +3414,8 @@  void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 #endif /* CONFIG_AP */
 #ifdef CONFIG_TDLS
 		if (data)
-			wpa_tdls_disable_link(wpa_s->wpa, data->low_ack.addr);
+			wpa_tdls_disable_unreachable_link(wpa_s->wpa,
+							  data->low_ack.addr);
 #endif /* CONFIG_TDLS */
 		break;
 	case EVENT_IBSS_PEER_LOST: