diff mbox

[3/7] TDLS: set the initiator during tdls_mgmt operations

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

Commit Message

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

Some drivers need to know the initiator of a TDLS connection in order
to generate a correct TDLS mgmt packet. It is used to determine
the link identifier IE. Pass this information to the driver.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
---
 src/drivers/driver.h         |    3 ++-
 src/drivers/driver_nl80211.c |    5 ++++-
 src/rsn_supp/tdls.c          |   40 ++++++++++++++++++++++++----------------
 src/rsn_supp/wpa.h           |    2 +-
 src/rsn_supp/wpa_i.h         |    6 ++++--
 wpa_supplicant/driver_i.h    |    6 +++---
 wpa_supplicant/wpas_glue.c   |    6 ++++--
 7 files changed, 42 insertions(+), 26 deletions(-)

Comments

Ilan Peer June 11, 2014, 6:11 a.m. UTC | #1
Hi,

Please drop this patch. The needed change in nl80211.h is not in wireless-testing.

Sorry,

Ilan.

> -----Original Message-----
> From: hostap-bounces@lists.shmoo.com [mailto:hostap-
> bounces@lists.shmoo.com] On Behalf Of Ilan Peer
> Sent: Tuesday, June 10, 2014 21:19
> To: hostap@lists.shmoo.com
> Cc: Arik Nemtsov; Nemtsov, ArikX
> Subject: [PATCH 3/7] TDLS: set the initiator during tdls_mgmt operations
> 
> From: Arik Nemtsov <arik@wizery.com>
> 
> Some drivers need to know the initiator of a TDLS connection in order to
> generate a correct TDLS mgmt packet. It is used to determine the link
> identifier IE. Pass this information to the driver.
> 
> Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
> ---
>  src/drivers/driver.h         |    3 ++-
>  src/drivers/driver_nl80211.c |    5 ++++-
>  src/rsn_supp/tdls.c          |   40 ++++++++++++++++++++++++----------------
>  src/rsn_supp/wpa.h           |    2 +-
>  src/rsn_supp/wpa_i.h         |    6 ++++--
>  wpa_supplicant/driver_i.h    |    6 +++---
>  wpa_supplicant/wpas_glue.c   |    6 ++++--
>  7 files changed, 42 insertions(+), 26 deletions(-)
> 
> diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 6e47b86..51ea378
> 100644
> --- a/src/drivers/driver.h
> +++ b/src/drivers/driver.h
> @@ -2495,6 +2495,7 @@ struct wpa_driver_ops {
>  	 * @dialog_token: Dialog Token to use in the message (if needed)
>  	 * @status_code: Status Code or Reason Code to use (if needed)
>  	 * @peer_capab: TDLS peer capability (TDLS_PEER_* bitfield)
> +	 * @initiator: Is the current end the TDLS link initiator
>  	 * @buf: TDLS IEs to add to the message
>  	 * @len: Length of buf in octets
>  	 * Returns: 0 on success, negative (<0) on failure @@ -2504,7 +2505,7
> @@ struct wpa_driver_ops {
>  	 */
>  	int (*send_tdls_mgmt)(void *priv, const u8 *dst, u8 action_code,
>  			      u8 dialog_token, u16 status_code, u32
> peer_capab,
> -			      const u8 *buf, size_t len);
> +			      u8 initiator, const u8 *buf, size_t len);
> 
>  	/**
>  	 * tdls_oper - Ask the driver to perform high-level TDLS operations
> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index
> 7568653..3572fef 100644
> --- a/src/drivers/driver_nl80211.c
> +++ b/src/drivers/driver_nl80211.c
> @@ -11435,7 +11435,8 @@ nla_put_failure:
> 
>  static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8
> action_code,
>  				  u8 dialog_token, u16 status_code,
> -				  u32 peer_capab, const u8 *buf, size_t len)
> +				  u32 peer_capab, u8 initiator, const u8 *buf,
> +				  size_t len)
>  {
>  	struct i802_bss *bss = priv;
>  	struct wpa_driver_nl80211_data *drv = bss->drv; @@ -11466,6
> +11467,8 @@ static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst,
> u8 action_code,
>  		 */
>  		NLA_PUT_U32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY,
> peer_capab);
>  	}
> +	if (initiator)
> +		NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_INITIATOR);
>  	NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
> 
>  	return send_and_recv_msgs(drv, msg, NULL, NULL); diff --git
> a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index e712a4d..f0ef6c7 100644
> --- a/src/rsn_supp/tdls.c
> +++ b/src/rsn_supp/tdls.c
> @@ -218,26 +218,29 @@ static int wpa_tdls_set_key(struct wpa_sm *sm,
> struct wpa_tdls_peer *peer)  static int wpa_tdls_send_tpk_msg(struct
> wpa_sm *sm, const u8 *dst,
>  				 u8 action_code, u8 dialog_token,
>  				 u16 status_code, u32 peer_capab,
> -				 const u8 *buf, size_t len)
> +				 u8 initiator, const u8 *buf, size_t len)
>  {
>  	return wpa_sm_send_tdls_mgmt(sm, dst, action_code,
> dialog_token,
> -				     status_code, peer_capab, buf, len);
> +				     status_code, peer_capab, initiator, buf,
> +				     len);
>  }
> 
> 
>  static int wpa_tdls_tpk_send(struct wpa_sm *sm, const u8 *dest, u8
> action_code,
>  			     u8 dialog_token, u16 status_code, u32
> peer_capab,
> -			     const u8 *msg, size_t msg_len)
> +			     u8 initiator, const u8 *msg, size_t msg_len)
>  {
>  	struct wpa_tdls_peer *peer;
> 
>  	wpa_printf(MSG_DEBUG, "TDLS: TPK send dest=" MACSTR "
> action_code=%u "
> -		   "dialog_token=%u status_code=%u peer_capab=%u
> msg_len=%u",
> +		   "dialog_token=%u status_code=%u peer_capab=%u
> initiator=%u "
> +		   "msg_len=%u",
>  		   MAC2STR(dest), action_code, dialog_token, status_code,
> -		   peer_capab, (unsigned int) msg_len);
> +		   peer_capab, initiator, (unsigned int) msg_len);
> 
>  	if (wpa_tdls_send_tpk_msg(sm, dest, action_code, dialog_token,
> -				  status_code, peer_capab, msg, msg_len)) {
> +				  status_code, peer_capab, initiator, msg,
> +				  msg_len)) {
>  		wpa_printf(MSG_INFO, "TDLS: Failed to send message "
>  			   "(action_code=%u)", action_code);
>  		return -1;
> @@ -333,6 +336,7 @@ static void wpa_tdls_tpk_retry_timeout(void
> *eloop_ctx, void *timeout_ctx)
>  					  peer->sm_tmr.dialog_token,
>  					  peer->sm_tmr.status_code,
>  					  peer->sm_tmr.peer_capab,
> +					  peer->initiator,
>  					  peer->sm_tmr.buf,
>  					  peer->sm_tmr.buf_len)) {
>  			wpa_printf(MSG_INFO, "TDLS: Failed to retry "
> @@ -759,7 +763,7 @@ skip_ies:
> 
>  	/* request driver to send Teardown using this FTIE */
>  	wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_TEARDOWN, 0,
> -			  reason_code, 0, rbuf, pos - rbuf);
> +			  reason_code, 0, peer->initiator, rbuf, pos - rbuf);
>  	os_free(rbuf);
> 
>  	return 0;
> @@ -934,17 +938,19 @@ skip_ftie:
>   *	appropriate status code mentioning reason for error/failure.
>   * @dst 	- MAC addr of Peer station
>   * @tdls_action - TDLS frame type for which error code is sent
> + * @initiator   - was this end the initiator of the connection
>   * @status 	- status code mentioning reason
>   */
> 
>  static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst,
> -			       u8 tdls_action, u8 dialog_token, u16 status)
> +			       u8 tdls_action, u8 dialog_token, u8 initiator,
> +			       u16 status)
>  {
>  	wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
>  		   " (action=%u status=%u)",
>  		   MAC2STR(dst), tdls_action, status);
>  	return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
> -				 0, NULL, 0);
> +				 0, initiator, NULL, 0);
>  }
> 
> 
> @@ -1150,7 +1156,7 @@ skip_ies:
>  		   MAC2STR(peer->addr));
> 
>  	status = wpa_tdls_tpk_send(sm, peer->addr,
> WLAN_TDLS_SETUP_REQUEST,
> -				   1, 0, 0, rbuf, pos - rbuf);
> +				   1, 0, 0, peer->initiator, rbuf, pos - rbuf);
>  	os_free(rbuf);
> 
>  	return status;
> @@ -1240,7 +1246,8 @@ static int wpa_tdls_send_tpk_m2(struct wpa_sm
> *sm,
> 
>  skip_ies:
>  	status = wpa_tdls_tpk_send(sm, src_addr,
> WLAN_TDLS_SETUP_RESPONSE,
> -				   dtoken, 0, 0, rbuf, pos - rbuf);
> +				   dtoken, 0, 0, peer->initiator, rbuf,
> +				   pos - rbuf);
>  	os_free(rbuf);
> 
>  	return status;
> @@ -1337,7 +1344,8 @@ skip_ies:
>  		peer_capab |= TDLS_PEER_WMM;
> 
>  	status = wpa_tdls_tpk_send(sm, src_addr,
> WLAN_TDLS_SETUP_CONFIRM,
> -				   dtoken, 0, peer_capab, rbuf, pos - rbuf);
> +				   dtoken, 0, peer_capab, peer->initiator,
> +				   rbuf, pos - rbuf);
>  	os_free(rbuf);
> 
>  	return status;
> @@ -1352,7 +1360,7 @@ static int
> wpa_tdls_send_discovery_response(struct wpa_sm *sm,
>  		   "(peer " MACSTR ")", MAC2STR(peer->addr));
> 
>  	return wpa_tdls_tpk_send(sm, peer->addr,
> WLAN_TDLS_DISCOVERY_RESPONSE,
> -				 dialog_token, 0, 0, NULL, 0);
> +				 dialog_token, 0, 0, 0, NULL, 0);
>  }
> 
> 
> @@ -1413,7 +1421,7 @@ int wpa_tdls_send_discovery_request(struct
> wpa_sm *sm, const u8 *addr)
>  	wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer
> "
>  		   MACSTR, MAC2STR(addr));
>  	return wpa_tdls_tpk_send(sm, addr,
> WLAN_TDLS_DISCOVERY_REQUEST,
> -				 1, 0, 0, NULL, 0);
> +				 1, 0, 0, 1, NULL, 0);
>  }
> 
> 
> @@ -1919,7 +1927,7 @@ skip_rsn_check:
> 
>  error:
>  	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE,
> dtoken,
> -			    status);
> +			    peer->initiator, status);
>  	wpa_tdls_peer_free(sm, peer);
>  	return -1;
>  }
> @@ -2241,7 +2249,7 @@ skip_rsn:
> 
>  error:
>  	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM,
> dtoken,
> -			    status);
> +			    peer->initiator, status);
>  	wpa_tdls_disable_peer_link(sm, peer);
>  	return -1;
>  }
> diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index
> 07a7bf9..574e970 100644
> --- a/src/rsn_supp/wpa.h
> +++ b/src/rsn_supp/wpa.h
> @@ -55,7 +55,7 @@ struct wpa_sm_ctx {
>  	int (*send_tdls_mgmt)(void *ctx, const u8 *dst,
>  			      u8 action_code, u8 dialog_token,
>  			      u16 status_code, u32 peer_capab,
> -			      const u8 *buf, size_t len);
> +			      u8 initiator, const u8 *buf, size_t len);
>  	int (*tdls_oper)(void *ctx, int oper, const u8 *peer);
>  	int (*tdls_peer_addset)(void *ctx, const u8 *addr, int add, u16 aid,
>  				u16 capability, const u8 *supp_rates, diff --git
> a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index e20e9da..ea12c6f
> 100644
> --- a/src/rsn_supp/wpa_i.h
> +++ b/src/rsn_supp/wpa_i.h
> @@ -268,12 +268,14 @@ static inline int wpa_sm_tdls_get_capa(struct
> wpa_sm *sm,  static inline int wpa_sm_send_tdls_mgmt(struct wpa_sm
> *sm, const u8 *dst,
>  					u8 action_code, u8 dialog_token,
>  					u16 status_code, u32 peer_capab,
> -					const u8 *buf, size_t len)
> +					u8 initiator, const u8 *buf,
> +					size_t len)
>  {
>  	if (sm->ctx->send_tdls_mgmt)
>  		return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst,
> action_code,
>  					       dialog_token, status_code,
> -					       peer_capab, buf, len);
> +					       peer_capab, initiator, buf,
> +					       len);
>  	return -1;
>  }
> 
> diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index
> 00703d9..2a41c85 100644
> --- a/wpa_supplicant/driver_i.h
> +++ b/wpa_supplicant/driver_i.h
> @@ -532,14 +532,14 @@ static inline int wpa_drv_ampdu(struct
> wpa_supplicant *wpa_s, int ampdu)  static inline int
> wpa_drv_send_tdls_mgmt(struct wpa_supplicant *wpa_s,
>  					 const u8 *dst, u8 action_code,
>  					 u8 dialog_token, u16 status_code,
> -					 u32 peer_capab, const u8 *buf,
> -					 size_t len)
> +					 u32 peer_capab, u8 initiator,
> +					 const u8 *buf, size_t len)
>  {
>  	if (wpa_s->driver->send_tdls_mgmt) {
>  		return wpa_s->driver->send_tdls_mgmt(wpa_s->drv_priv,
> dst,
>  						     action_code, dialog_token,
>  						     status_code, peer_capab,
> -						     buf, len);
> +						     initiator, buf, len);
>  	}
>  	return -1;
>  }
> diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
> index 350b122..b7ab4f7 100644
> --- a/wpa_supplicant/wpas_glue.c
> +++ b/wpa_supplicant/wpas_glue.c
> @@ -562,11 +562,13 @@ static int wpa_supplicant_tdls_get_capa(void *ctx,
> int *tdls_supported,  static int wpa_supplicant_send_tdls_mgmt(void *ctx,
> const u8 *dst,
>  					 u8 action_code, u8 dialog_token,
>  					 u16 status_code, u32 peer_capab,
> -					 const u8 *buf, size_t len)
> +					 u8 initiator, const u8 *buf,
> +					 size_t len)
>  {
>  	struct wpa_supplicant *wpa_s = ctx;
>  	return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code,
> dialog_token,
> -				      status_code, peer_capab, buf, len);
> +				      status_code, peer_capab, initiator, buf,
> +				      len);
>  }
> 
> 
> --
> 1.7.10.4
> 
> _______________________________________________
> HostAP mailing list
> HostAP@lists.shmoo.com
> http://lists.shmoo.com/mailman/listinfo/hostap
diff mbox

Patch

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 6e47b86..51ea378 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2495,6 +2495,7 @@  struct wpa_driver_ops {
 	 * @dialog_token: Dialog Token to use in the message (if needed)
 	 * @status_code: Status Code or Reason Code to use (if needed)
 	 * @peer_capab: TDLS peer capability (TDLS_PEER_* bitfield)
+	 * @initiator: Is the current end the TDLS link initiator
 	 * @buf: TDLS IEs to add to the message
 	 * @len: Length of buf in octets
 	 * Returns: 0 on success, negative (<0) on failure
@@ -2504,7 +2505,7 @@  struct wpa_driver_ops {
 	 */
 	int (*send_tdls_mgmt)(void *priv, const u8 *dst, u8 action_code,
 			      u8 dialog_token, u16 status_code, u32 peer_capab,
-			      const u8 *buf, size_t len);
+			      u8 initiator, const u8 *buf, size_t len);
 
 	/**
 	 * tdls_oper - Ask the driver to perform high-level TDLS operations
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 7568653..3572fef 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -11435,7 +11435,8 @@  nla_put_failure:
 
 static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
 				  u8 dialog_token, u16 status_code,
-				  u32 peer_capab, const u8 *buf, size_t len)
+				  u32 peer_capab, u8 initiator, const u8 *buf,
+				  size_t len)
 {
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -11466,6 +11467,8 @@  static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
 		 */
 		NLA_PUT_U32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY, peer_capab);
 	}
+	if (initiator)
+		NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_INITIATOR);
 	NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
 
 	return send_and_recv_msgs(drv, msg, NULL, NULL);
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index e712a4d..f0ef6c7 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -218,26 +218,29 @@  static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
 static int wpa_tdls_send_tpk_msg(struct wpa_sm *sm, const u8 *dst,
 				 u8 action_code, u8 dialog_token,
 				 u16 status_code, u32 peer_capab,
-				 const u8 *buf, size_t len)
+				 u8 initiator, const u8 *buf, size_t len)
 {
 	return wpa_sm_send_tdls_mgmt(sm, dst, action_code, dialog_token,
-				     status_code, peer_capab, buf, len);
+				     status_code, peer_capab, initiator, buf,
+				     len);
 }
 
 
 static int wpa_tdls_tpk_send(struct wpa_sm *sm, const u8 *dest, u8 action_code,
 			     u8 dialog_token, u16 status_code, u32 peer_capab,
-			     const u8 *msg, size_t msg_len)
+			     u8 initiator, const u8 *msg, size_t msg_len)
 {
 	struct wpa_tdls_peer *peer;
 
 	wpa_printf(MSG_DEBUG, "TDLS: TPK send dest=" MACSTR " action_code=%u "
-		   "dialog_token=%u status_code=%u peer_capab=%u msg_len=%u",
+		   "dialog_token=%u status_code=%u peer_capab=%u initiator=%u "
+		   "msg_len=%u",
 		   MAC2STR(dest), action_code, dialog_token, status_code,
-		   peer_capab, (unsigned int) msg_len);
+		   peer_capab, initiator, (unsigned int) msg_len);
 
 	if (wpa_tdls_send_tpk_msg(sm, dest, action_code, dialog_token,
-				  status_code, peer_capab, msg, msg_len)) {
+				  status_code, peer_capab, initiator, msg,
+				  msg_len)) {
 		wpa_printf(MSG_INFO, "TDLS: Failed to send message "
 			   "(action_code=%u)", action_code);
 		return -1;
@@ -333,6 +336,7 @@  static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx)
 					  peer->sm_tmr.dialog_token,
 					  peer->sm_tmr.status_code,
 					  peer->sm_tmr.peer_capab,
+					  peer->initiator,
 					  peer->sm_tmr.buf,
 					  peer->sm_tmr.buf_len)) {
 			wpa_printf(MSG_INFO, "TDLS: Failed to retry "
@@ -759,7 +763,7 @@  skip_ies:
 
 	/* request driver to send Teardown using this FTIE */
 	wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_TEARDOWN, 0,
-			  reason_code, 0, rbuf, pos - rbuf);
+			  reason_code, 0, peer->initiator, rbuf, pos - rbuf);
 	os_free(rbuf);
 
 	return 0;
@@ -934,17 +938,19 @@  skip_ftie:
  *	appropriate status code mentioning reason for error/failure.
  * @dst 	- MAC addr of Peer station
  * @tdls_action - TDLS frame type for which error code is sent
+ * @initiator   - was this end the initiator of the connection
  * @status 	- status code mentioning reason
  */
 
 static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst,
-			       u8 tdls_action, u8 dialog_token, u16 status)
+			       u8 tdls_action, u8 dialog_token, u8 initiator,
+			       u16 status)
 {
 	wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
 		   " (action=%u status=%u)",
 		   MAC2STR(dst), tdls_action, status);
 	return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
-				 0, NULL, 0);
+				 0, initiator, NULL, 0);
 }
 
 
@@ -1150,7 +1156,7 @@  skip_ies:
 		   MAC2STR(peer->addr));
 
 	status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST,
-				   1, 0, 0, rbuf, pos - rbuf);
+				   1, 0, 0, peer->initiator, rbuf, pos - rbuf);
 	os_free(rbuf);
 
 	return status;
@@ -1240,7 +1246,8 @@  static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm,
 
 skip_ies:
 	status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE,
-				   dtoken, 0, 0, rbuf, pos - rbuf);
+				   dtoken, 0, 0, peer->initiator, rbuf,
+				   pos - rbuf);
 	os_free(rbuf);
 
 	return status;
@@ -1337,7 +1344,8 @@  skip_ies:
 		peer_capab |= TDLS_PEER_WMM;
 
 	status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM,
-				   dtoken, 0, peer_capab, rbuf, pos - rbuf);
+				   dtoken, 0, peer_capab, peer->initiator,
+				   rbuf, pos - rbuf);
 	os_free(rbuf);
 
 	return status;
@@ -1352,7 +1360,7 @@  static int wpa_tdls_send_discovery_response(struct wpa_sm *sm,
 		   "(peer " MACSTR ")", MAC2STR(peer->addr));
 
 	return wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE,
-				 dialog_token, 0, 0, NULL, 0);
+				 dialog_token, 0, 0, 0, NULL, 0);
 }
 
 
@@ -1413,7 +1421,7 @@  int wpa_tdls_send_discovery_request(struct wpa_sm *sm, const u8 *addr)
 	wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer "
 		   MACSTR, MAC2STR(addr));
 	return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST,
-				 1, 0, 0, NULL, 0);
+				 1, 0, 0, 1, NULL, 0);
 }
 
 
@@ -1919,7 +1927,7 @@  skip_rsn_check:
 
 error:
 	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken,
-			    status);
+			    peer->initiator, status);
 	wpa_tdls_peer_free(sm, peer);
 	return -1;
 }
@@ -2241,7 +2249,7 @@  skip_rsn:
 
 error:
 	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
-			    status);
+			    peer->initiator, status);
 	wpa_tdls_disable_peer_link(sm, peer);
 	return -1;
 }
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 07a7bf9..574e970 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -55,7 +55,7 @@  struct wpa_sm_ctx {
 	int (*send_tdls_mgmt)(void *ctx, const u8 *dst,
 			      u8 action_code, u8 dialog_token,
 			      u16 status_code, u32 peer_capab,
-			      const u8 *buf, size_t len);
+			      u8 initiator, const u8 *buf, size_t len);
 	int (*tdls_oper)(void *ctx, int oper, const u8 *peer);
 	int (*tdls_peer_addset)(void *ctx, const u8 *addr, int add, u16 aid,
 				u16 capability, const u8 *supp_rates,
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index e20e9da..ea12c6f 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -268,12 +268,14 @@  static inline int wpa_sm_tdls_get_capa(struct wpa_sm *sm,
 static inline int wpa_sm_send_tdls_mgmt(struct wpa_sm *sm, const u8 *dst,
 					u8 action_code, u8 dialog_token,
 					u16 status_code, u32 peer_capab,
-					const u8 *buf, size_t len)
+					u8 initiator, const u8 *buf,
+					size_t len)
 {
 	if (sm->ctx->send_tdls_mgmt)
 		return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst, action_code,
 					       dialog_token, status_code,
-					       peer_capab, buf, len);
+					       peer_capab, initiator, buf,
+					       len);
 	return -1;
 }
 
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 00703d9..2a41c85 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -532,14 +532,14 @@  static inline int wpa_drv_ampdu(struct wpa_supplicant *wpa_s, int ampdu)
 static inline int wpa_drv_send_tdls_mgmt(struct wpa_supplicant *wpa_s,
 					 const u8 *dst, u8 action_code,
 					 u8 dialog_token, u16 status_code,
-					 u32 peer_capab, const u8 *buf,
-					 size_t len)
+					 u32 peer_capab, u8 initiator,
+					 const u8 *buf, size_t len)
 {
 	if (wpa_s->driver->send_tdls_mgmt) {
 		return wpa_s->driver->send_tdls_mgmt(wpa_s->drv_priv, dst,
 						     action_code, dialog_token,
 						     status_code, peer_capab,
-						     buf, len);
+						     initiator, buf, len);
 	}
 	return -1;
 }
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 350b122..b7ab4f7 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -562,11 +562,13 @@  static int wpa_supplicant_tdls_get_capa(void *ctx, int *tdls_supported,
 static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
 					 u8 action_code, u8 dialog_token,
 					 u16 status_code, u32 peer_capab,
-					 const u8 *buf, size_t len)
+					 u8 initiator, const u8 *buf,
+					 size_t len)
 {
 	struct wpa_supplicant *wpa_s = ctx;
 	return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token,
-				      status_code, peer_capab, buf, len);
+				      status_code, peer_capab, initiator, buf,
+				      len);
 }