mac80211: avoid adding some IEs on TDLS setup failure packets

Most setup-specific information elements are not to be added when a
setup frame is sent with an error status code.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Reviewed-by: Liad Kaufman <liad.kaufman@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Arik Nemtsov 2014-07-17 17:14:21 +03:00 committed by Johannes Berg
parent f09a87d274
commit 1606ef4a9d

View File

@ -63,26 +63,36 @@ static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata)
return capab; return capab;
} }
static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr, static void ieee80211_tdls_add_link_ie(struct ieee80211_sub_if_data *sdata,
const u8 *peer, const u8 *bssid) struct sk_buff *skb, const u8 *peer,
bool initiator)
{ {
struct ieee80211_tdls_lnkie *lnkid; struct ieee80211_tdls_lnkie *lnkid;
const u8 *init_addr, *rsp_addr;
if (initiator) {
init_addr = sdata->vif.addr;
rsp_addr = peer;
} else {
init_addr = peer;
rsp_addr = sdata->vif.addr;
}
lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie)); lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
lnkid->ie_type = WLAN_EID_LINK_ID; lnkid->ie_type = WLAN_EID_LINK_ID;
lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2; lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
memcpy(lnkid->bssid, bssid, ETH_ALEN); memcpy(lnkid->bssid, sdata->u.mgd.bssid, ETH_ALEN);
memcpy(lnkid->init_sta, src_addr, ETH_ALEN); memcpy(lnkid->init_sta, init_addr, ETH_ALEN);
memcpy(lnkid->resp_sta, peer, ETH_ALEN); memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN);
} }
static void static void
ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, const u8 *peer, struct sk_buff *skb, const u8 *peer,
u8 action_code, const u8 *extra_ies, u8 action_code, bool initiator,
size_t extra_ies_len) const u8 *extra_ies, size_t extra_ies_len)
{ {
enum ieee80211_band band = ieee80211_get_sdata_band(sdata); enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
size_t offset = 0, noffset; size_t offset = 0, noffset;
@ -140,22 +150,26 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
pos = skb_put(skb, noffset - offset); pos = skb_put(skb, noffset - offset);
memcpy(pos, extra_ies + offset, noffset - offset); memcpy(pos, extra_ies + offset, noffset - offset);
} }
ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
} }
static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata, static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, const u8 *peer, struct sk_buff *skb, const u8 *peer,
u8 action_code, bool initiator, u8 action_code, u16 status_code,
const u8 *extra_ies, size_t extra_ies_len) bool initiator, const u8 *extra_ies,
size_t extra_ies_len)
{ {
const u8 *init_addr, *rsp_addr;
switch (action_code) { switch (action_code) {
case WLAN_TDLS_SETUP_REQUEST: case WLAN_TDLS_SETUP_REQUEST:
case WLAN_TDLS_SETUP_RESPONSE: case WLAN_TDLS_SETUP_RESPONSE:
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
ieee80211_tdls_add_setup_start_ies(sdata, skb, peer, if (status_code == 0)
action_code, extra_ies, ieee80211_tdls_add_setup_start_ies(sdata, skb, peer,
extra_ies_len); action_code,
initiator,
extra_ies,
extra_ies_len);
break; break;
case WLAN_TDLS_SETUP_CONFIRM: case WLAN_TDLS_SETUP_CONFIRM:
case WLAN_TDLS_TEARDOWN: case WLAN_TDLS_TEARDOWN:
@ -163,19 +177,11 @@ static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata,
if (extra_ies_len) if (extra_ies_len)
memcpy(skb_put(skb, extra_ies_len), extra_ies, memcpy(skb_put(skb, extra_ies_len), extra_ies,
extra_ies_len); extra_ies_len);
if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN)
ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
break; break;
} }
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);
} }
static int static int
@ -368,8 +374,8 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
if (ret < 0) if (ret < 0)
goto fail; goto fail;
ieee80211_tdls_add_ies(sdata, skb, peer, action_code, initiator, ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
extra_ies, extra_ies_len); initiator, extra_ies, extra_ies_len);
if (send_direct) { if (send_direct) {
ieee80211_tx_skb(sdata, skb); ieee80211_tx_skb(sdata, skb);
return 0; return 0;