Commit 2fb6b9b8 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Johannes Berg

mac80211: use TDLS initiator in tdls_mgmt operations

The TDLS initiator is set once during link setup. If determines the
address ordering in the link identifier IE.
Use the value from userspace in order to have a correct teardown packet.
With the current code, a teardown from the responder side fails the TDLS
MIC check because of a bad link identifier IE.
Signed-off-by: default avatarArik Nemtsov <arikx.nemtsov@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 31fa97c5
...@@ -193,13 +193,14 @@ static int ...@@ -193,13 +193,14 @@ static int
ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u8 action_code, const u8 *peer, u8 action_code,
u8 dialog_token, u16 status_code, u8 dialog_token, u16 status_code,
u32 peer_capability, const u8 *extra_ies, u32 peer_capability, bool initiator,
size_t extra_ies_len) const u8 *extra_ies, size_t extra_ies_len)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
bool send_direct; bool send_direct;
const u8 *init_addr, *rsp_addr;
int ret; int ret;
skb = dev_alloc_skb(local->hw.extra_tx_headroom + skb = dev_alloc_skb(local->hw.extra_tx_headroom +
...@@ -242,27 +243,42 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, ...@@ -242,27 +243,42 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
if (extra_ies_len) if (extra_ies_len)
memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
/* the TDLS link IE is always added last */ /* sanity check for initiator */
switch (action_code) { switch (action_code) {
case WLAN_TDLS_SETUP_REQUEST: case WLAN_TDLS_SETUP_REQUEST:
case WLAN_TDLS_SETUP_CONFIRM: case WLAN_TDLS_SETUP_CONFIRM:
case WLAN_TDLS_TEARDOWN:
case WLAN_TDLS_DISCOVERY_REQUEST: case WLAN_TDLS_DISCOVERY_REQUEST:
/* we are the initiator */ if (!initiator) {
ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer, ret = -EINVAL;
sdata->u.mgd.bssid); goto fail;
}
break; break;
case WLAN_TDLS_SETUP_RESPONSE: case WLAN_TDLS_SETUP_RESPONSE:
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
/* we are the responder */ if (initiator) {
ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr, ret = -EINVAL;
sdata->u.mgd.bssid); goto fail;
}
break;
case WLAN_TDLS_TEARDOWN:
/* any value is ok */
break; break;
default: default:
ret = -ENOTSUPP; ret = -ENOTSUPP;
goto fail; goto fail;
} }
if (initiator) {
init_addr = sdata->vif.addr;
rsp_addr = peer;
} else {
init_addr = peer;
rsp_addr = sdata->vif.addr;
}
ieee80211_tdls_add_link_ie(skb, init_addr, rsp_addr,
sdata->u.mgd.bssid);
if (send_direct) { if (send_direct) {
ieee80211_tx_skb(sdata, skb); ieee80211_tx_skb(sdata, skb);
return 0; return 0;
...@@ -327,8 +343,8 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, ...@@ -327,8 +343,8 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
dialog_token, status_code, dialog_token, status_code,
peer_capability, extra_ies, peer_capability, initiator,
extra_ies_len); extra_ies, extra_ies_len);
if (ret < 0) if (ret < 0)
goto exit; goto exit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment