From: Arik Nemtsov Date: Wed, 11 Jun 2014 14:18:22 +0000 (+0300) Subject: mac80211: use TDLS initiator in tdls_mgmt operations X-Git-Tag: v3.17-rc1~106^2~73^2~18^2~34 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=2fb6b9b8e5f08df31bc4081b4d9f38701c59cfd3;p=karo-tx-linux.git 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: Arik Nemtsov Signed-off-by: Johannes Berg --- diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 0b3ca2ce7ea4..c4a9af3b75e5 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -193,13 +193,14 @@ static int ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, const u8 *peer, u8 action_code, u8 dialog_token, u16 status_code, - u32 peer_capability, const u8 *extra_ies, - size_t extra_ies_len) + u32 peer_capability, bool initiator, + const u8 *extra_ies, size_t extra_ies_len) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; struct sk_buff *skb = NULL; bool send_direct; + const u8 *init_addr, *rsp_addr; int ret; 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, if (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) { case WLAN_TDLS_SETUP_REQUEST: case WLAN_TDLS_SETUP_CONFIRM: - case WLAN_TDLS_TEARDOWN: case WLAN_TDLS_DISCOVERY_REQUEST: - /* we are the initiator */ - ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer, - sdata->u.mgd.bssid); + if (!initiator) { + ret = -EINVAL; + goto fail; + } break; case WLAN_TDLS_SETUP_RESPONSE: case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: - /* we are the responder */ - ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr, - sdata->u.mgd.bssid); + if (initiator) { + ret = -EINVAL; + goto fail; + } + break; + case WLAN_TDLS_TEARDOWN: + /* any value is ok */ break; default: ret = -ENOTSUPP; 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) { ieee80211_tx_skb(sdata, skb); return 0; @@ -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, dialog_token, status_code, - peer_capability, extra_ies, - extra_ies_len); + peer_capability, initiator, + extra_ies, extra_ies_len); if (ret < 0) goto exit;