TDLS: Set the initiator during tdls_mgmt operations

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>
This commit is contained in:
Arik Nemtsov 2014-09-29 20:47:51 +02:00 committed by Jouni Malinen
parent 01cb5df20c
commit 984dadc23a
7 changed files with 42 additions and 26 deletions

View file

@ -2503,6 +2503,7 @@ struct wpa_driver_ops {
* @dialog_token: Dialog Token to use in the message (if needed) * @dialog_token: Dialog Token to use in the message (if needed)
* @status_code: Status Code or Reason Code to use (if needed) * @status_code: Status Code or Reason Code to use (if needed)
* @peer_capab: TDLS peer capability (TDLS_PEER_* bitfield) * @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 * @buf: TDLS IEs to add to the message
* @len: Length of buf in octets * @len: Length of buf in octets
* Returns: 0 on success, negative (<0) on failure * Returns: 0 on success, negative (<0) on failure
@ -2512,7 +2513,7 @@ struct wpa_driver_ops {
*/ */
int (*send_tdls_mgmt)(void *priv, const u8 *dst, u8 action_code, int (*send_tdls_mgmt)(void *priv, const u8 *dst, u8 action_code,
u8 dialog_token, u16 status_code, u32 peer_capab, u8 dialog_token, u16 status_code, u32 peer_capab,
const u8 *buf, size_t len); int initiator, const u8 *buf, size_t len);
/** /**
* tdls_oper - Ask the driver to perform high-level TDLS operations * tdls_oper - Ask the driver to perform high-level TDLS operations

View file

@ -11605,7 +11605,8 @@ nla_put_failure:
static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code, static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
u8 dialog_token, u16 status_code, u8 dialog_token, u16 status_code,
u32 peer_capab, const u8 *buf, size_t len) u32 peer_capab, int initiator, const u8 *buf,
size_t len)
{ {
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
@ -11636,6 +11637,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); 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); NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
return send_and_recv_msgs(drv, msg, NULL, NULL); return send_and_recv_msgs(drv, msg, NULL, NULL);

View file

@ -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, static int wpa_tdls_send_tpk_msg(struct wpa_sm *sm, const u8 *dst,
u8 action_code, u8 dialog_token, u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capab, u16 status_code, u32 peer_capab,
const u8 *buf, size_t len) int initiator, const u8 *buf, size_t len)
{ {
return wpa_sm_send_tdls_mgmt(sm, dst, action_code, dialog_token, 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, 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, u8 dialog_token, u16 status_code, u32 peer_capab,
const u8 *msg, size_t msg_len) int initiator, const u8 *msg, size_t msg_len)
{ {
struct wpa_tdls_peer *peer; struct wpa_tdls_peer *peer;
wpa_printf(MSG_DEBUG, "TDLS: TPK send dest=" MACSTR " action_code=%u " 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=%d "
"msg_len=%u",
MAC2STR(dest), action_code, dialog_token, status_code, 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, 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 " wpa_printf(MSG_INFO, "TDLS: Failed to send message "
"(action_code=%u)", action_code); "(action_code=%u)", action_code);
return -1; 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.dialog_token,
peer->sm_tmr.status_code, peer->sm_tmr.status_code,
peer->sm_tmr.peer_capab, peer->sm_tmr.peer_capab,
peer->initiator,
peer->sm_tmr.buf, peer->sm_tmr.buf,
peer->sm_tmr.buf_len)) { peer->sm_tmr.buf_len)) {
wpa_printf(MSG_INFO, "TDLS: Failed to retry " wpa_printf(MSG_INFO, "TDLS: Failed to retry "
@ -793,7 +797,7 @@ skip_ies:
/* request driver to send Teardown using this FTIE */ /* request driver to send Teardown using this FTIE */
wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_TEARDOWN, 0, 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); os_free(rbuf);
return 0; return 0;
@ -968,17 +972,19 @@ skip_ftie:
* appropriate status code mentioning reason for error/failure. * appropriate status code mentioning reason for error/failure.
* @dst - MAC addr of Peer station * @dst - MAC addr of Peer station
* @tdls_action - TDLS frame type for which error code is sent * @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 * @status - status code mentioning reason
*/ */
static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst, 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, int initiator,
u16 status)
{ {
wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
" (action=%u status=%u)", " (action=%u status=%u)",
MAC2STR(dst), tdls_action, status); MAC2STR(dst), tdls_action, status);
return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status, return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
0, NULL, 0); 0, initiator, NULL, 0);
} }
@ -1184,7 +1190,7 @@ skip_ies:
MAC2STR(peer->addr)); MAC2STR(peer->addr));
status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST, 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); os_free(rbuf);
return status; return status;
@ -1274,7 +1280,8 @@ static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm,
skip_ies: skip_ies:
status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, 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); os_free(rbuf);
return status; return status;
@ -1371,7 +1378,8 @@ skip_ies:
peer_capab |= TDLS_PEER_WMM; peer_capab |= TDLS_PEER_WMM;
status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, 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); os_free(rbuf);
return status; return status;
@ -1457,7 +1465,7 @@ skip_rsn_ies:
wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime); wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);
skip_ies: skip_ies:
status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE, status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE,
dialog_token, 0, 0, rbuf, pos - rbuf); dialog_token, 0, 0, 0, rbuf, pos - rbuf);
os_free(rbuf); os_free(rbuf);
return status; return status;
@ -1528,7 +1536,7 @@ int wpa_tdls_send_discovery_request(struct wpa_sm *sm, const u8 *addr)
wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer " wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer "
MACSTR, MAC2STR(addr)); MACSTR, MAC2STR(addr));
return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST, return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST,
1, 0, 0, NULL, 0); 1, 0, 0, 1, NULL, 0);
} }
@ -2051,7 +2059,7 @@ skip_rsn_check:
return 0; return 0;
error: error:
wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0,
status); status);
if (peer) if (peer)
wpa_tdls_peer_free(sm, peer); wpa_tdls_peer_free(sm, peer);
@ -2362,7 +2370,7 @@ skip_rsn:
return ret; return ret;
error: error:
wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 1,
status); status);
wpa_tdls_disable_peer_link(sm, peer); wpa_tdls_disable_peer_link(sm, peer);
return -1; return -1;

View file

@ -55,7 +55,7 @@ struct wpa_sm_ctx {
int (*send_tdls_mgmt)(void *ctx, const u8 *dst, int (*send_tdls_mgmt)(void *ctx, const u8 *dst,
u8 action_code, u8 dialog_token, u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capab, u16 status_code, u32 peer_capab,
const u8 *buf, size_t len); int initiator, const u8 *buf, size_t len);
int (*tdls_oper)(void *ctx, int oper, const u8 *peer); int (*tdls_oper)(void *ctx, int oper, const u8 *peer);
int (*tdls_peer_addset)(void *ctx, const u8 *addr, int add, u16 aid, int (*tdls_peer_addset)(void *ctx, const u8 *addr, int add, u16 aid,
u16 capability, const u8 *supp_rates, u16 capability, const u8 *supp_rates,

View file

@ -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, static inline int wpa_sm_send_tdls_mgmt(struct wpa_sm *sm, const u8 *dst,
u8 action_code, u8 dialog_token, u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capab, u16 status_code, u32 peer_capab,
const u8 *buf, size_t len) int initiator, const u8 *buf,
size_t len)
{ {
if (sm->ctx->send_tdls_mgmt) if (sm->ctx->send_tdls_mgmt)
return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst, action_code, return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst, action_code,
dialog_token, status_code, dialog_token, status_code,
peer_capab, buf, len); peer_capab, initiator, buf,
len);
return -1; return -1;
} }

View file

@ -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, static inline int wpa_drv_send_tdls_mgmt(struct wpa_supplicant *wpa_s,
const u8 *dst, u8 action_code, const u8 *dst, u8 action_code,
u8 dialog_token, u16 status_code, u8 dialog_token, u16 status_code,
u32 peer_capab, const u8 *buf, u32 peer_capab, int initiator,
size_t len) const u8 *buf, size_t len)
{ {
if (wpa_s->driver->send_tdls_mgmt) { if (wpa_s->driver->send_tdls_mgmt) {
return wpa_s->driver->send_tdls_mgmt(wpa_s->drv_priv, dst, return wpa_s->driver->send_tdls_mgmt(wpa_s->drv_priv, dst,
action_code, dialog_token, action_code, dialog_token,
status_code, peer_capab, status_code, peer_capab,
buf, len); initiator, buf, len);
} }
return -1; return -1;
} }

View file

@ -580,11 +580,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, static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
u8 action_code, u8 dialog_token, u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capab, u16 status_code, u32 peer_capab,
const u8 *buf, size_t len) int initiator, const u8 *buf,
size_t len)
{ {
struct wpa_supplicant *wpa_s = ctx; struct wpa_supplicant *wpa_s = ctx;
return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token, 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);
} }