wlantest: Maintain only a single entry for an active direct link
The TDLS link itself is bidirectional, but there is explicit initiator/responder roles. Remove the other direction of the link if it exists when processing TDLS Setup Confirm to make sure that the link counters are stored for the current TDLS entery. This is also changing the control interface search for TDLS counters to require initiator/responder addresses in the correct order instead of matching entries regardless of the role.
This commit is contained in:
parent
eb4923fdae
commit
0d2e395d74
4 changed files with 40 additions and 9 deletions
|
@ -67,6 +67,13 @@ void pmk_deinit(struct wlantest_pmk *pmk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void tdls_deinit(struct wlantest_tdls *tdls)
|
||||||
|
{
|
||||||
|
dl_list_del(&tdls->list);
|
||||||
|
os_free(tdls);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void bss_deinit(struct wlantest_bss *bss)
|
void bss_deinit(struct wlantest_bss *bss)
|
||||||
{
|
{
|
||||||
struct wlantest_sta *sta, *n;
|
struct wlantest_sta *sta, *n;
|
||||||
|
@ -77,7 +84,7 @@ void bss_deinit(struct wlantest_bss *bss)
|
||||||
dl_list_for_each_safe(pmk, np, &bss->pmk, struct wlantest_pmk, list)
|
dl_list_for_each_safe(pmk, np, &bss->pmk, struct wlantest_pmk, list)
|
||||||
pmk_deinit(pmk);
|
pmk_deinit(pmk);
|
||||||
dl_list_for_each_safe(tdls, nt, &bss->tdls, struct wlantest_tdls, list)
|
dl_list_for_each_safe(tdls, nt, &bss->tdls, struct wlantest_tdls, list)
|
||||||
os_free(tdls);
|
tdls_deinit(tdls);
|
||||||
dl_list_del(&bss->list);
|
dl_list_del(&bss->list);
|
||||||
os_free(bss);
|
os_free(bss);
|
||||||
}
|
}
|
||||||
|
|
|
@ -444,8 +444,7 @@ static void ctrl_get_tdls_counter(struct wlantest *wt, int sock, u8 *cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
|
dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
|
||||||
if ((tdls->init == sta && tdls->resp == sta2) ||
|
if (tdls->init == sta && tdls->resp == sta2) {
|
||||||
(tdls->init == sta2 && tdls->resp == sta)) {
|
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
#include "wlantest.h"
|
#include "wlantest.h"
|
||||||
|
|
||||||
|
|
||||||
static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *linkid)
|
static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *linkid,
|
||||||
|
int create_new)
|
||||||
{
|
{
|
||||||
struct wlantest_bss *bss;
|
struct wlantest_bss *bss;
|
||||||
struct wlantest_sta *init, *resp;
|
struct wlantest_sta *init, *resp;
|
||||||
|
@ -46,6 +47,9 @@ static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *linkid)
|
||||||
return tdls;
|
return tdls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!create_new)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
tdls = os_zalloc(sizeof(*tdls));
|
tdls = os_zalloc(sizeof(*tdls));
|
||||||
if (tdls == NULL)
|
if (tdls == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -202,7 +206,7 @@ static void rx_data_tdls_setup_request(struct wlantest *wt, const u8 *bssid,
|
||||||
" initiator STA " MACSTR " responder STA " MACSTR,
|
" initiator STA " MACSTR " responder STA " MACSTR,
|
||||||
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
|
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
|
||||||
MAC2STR(elems.link_id + 2 * ETH_ALEN));
|
MAC2STR(elems.link_id + 2 * ETH_ALEN));
|
||||||
tdls = get_tdls(wt, elems.link_id);
|
tdls = get_tdls(wt, elems.link_id, 1);
|
||||||
if (tdls)
|
if (tdls)
|
||||||
tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_REQ]++;
|
tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_REQ]++;
|
||||||
}
|
}
|
||||||
|
@ -234,7 +238,7 @@ static void rx_data_tdls_setup_response(struct wlantest *wt, const u8 *bssid,
|
||||||
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
|
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
|
||||||
MAC2STR(elems.link_id + 2 * ETH_ALEN));
|
MAC2STR(elems.link_id + 2 * ETH_ALEN));
|
||||||
|
|
||||||
tdls = get_tdls(wt, elems.link_id);
|
tdls = get_tdls(wt, elems.link_id, 1);
|
||||||
if (!tdls)
|
if (!tdls)
|
||||||
return;
|
return;
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -259,6 +263,7 @@ static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
|
||||||
u16 status;
|
u16 status;
|
||||||
struct ieee802_11_elems elems;
|
struct ieee802_11_elems elems;
|
||||||
struct wlantest_tdls *tdls;
|
struct wlantest_tdls *tdls;
|
||||||
|
u8 link_id[3 * ETH_ALEN];
|
||||||
|
|
||||||
if (len < 3)
|
if (len < 3)
|
||||||
return;
|
return;
|
||||||
|
@ -275,7 +280,7 @@ static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
|
||||||
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
|
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
|
||||||
MAC2STR(elems.link_id + 2 * ETH_ALEN));
|
MAC2STR(elems.link_id + 2 * ETH_ALEN));
|
||||||
|
|
||||||
tdls = get_tdls(wt, elems.link_id);
|
tdls = get_tdls(wt, elems.link_id, 1);
|
||||||
if (tdls == NULL)
|
if (tdls == NULL)
|
||||||
return;
|
return;
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -287,13 +292,32 @@ static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tdls->link_up = 1;
|
tdls->link_up = 1;
|
||||||
if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1)
|
if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1) {
|
||||||
|
if (elems.ftie == NULL)
|
||||||
|
goto remove_reverse;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (tdls_verify_mic(tdls, 3, &elems) == 0) {
|
if (tdls_verify_mic(tdls, 3, &elems) == 0) {
|
||||||
tdls->dialog_token = data[2];
|
tdls->dialog_token = data[2];
|
||||||
wpa_printf(MSG_DEBUG, "TDLS: Dialog Token for the link: %u",
|
wpa_printf(MSG_DEBUG, "TDLS: Dialog Token for the link: %u",
|
||||||
tdls->dialog_token);
|
tdls->dialog_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remove_reverse:
|
||||||
|
/*
|
||||||
|
* The TDLS link itself is bidirectional, but there is explicit
|
||||||
|
* initiator/responder roles. Remove the other direction of the link
|
||||||
|
* (if it exists) to make sure that the link counters are stored for
|
||||||
|
* the current TDLS entery.
|
||||||
|
*/
|
||||||
|
os_memcpy(link_id, elems.link_id, ETH_ALEN);
|
||||||
|
os_memcpy(link_id + ETH_ALEN, elems.link_id + 2 * ETH_ALEN, ETH_ALEN);
|
||||||
|
os_memcpy(link_id + 2 * ETH_ALEN, elems.link_id + ETH_ALEN, ETH_ALEN);
|
||||||
|
tdls = get_tdls(wt, link_id, 0);
|
||||||
|
if (tdls) {
|
||||||
|
wpa_printf(MSG_DEBUG, "TDLS: Remove reverse link entry");
|
||||||
|
tdls_deinit(tdls);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -377,7 +401,7 @@ static void rx_data_tdls_teardown(struct wlantest *wt, const u8 *bssid,
|
||||||
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
|
MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
|
||||||
MAC2STR(elems.link_id + 2 * ETH_ALEN));
|
MAC2STR(elems.link_id + 2 * ETH_ALEN));
|
||||||
|
|
||||||
tdls = get_tdls(wt, elems.link_id);
|
tdls = get_tdls(wt, elems.link_id, 1);
|
||||||
if (tdls) {
|
if (tdls) {
|
||||||
tdls->link_up = 0;
|
tdls->link_up = 0;
|
||||||
tdls_verify_mic_teardown(tdls, 4, data, &elems);
|
tdls_verify_mic_teardown(tdls, 4, data, &elems);
|
||||||
|
|
|
@ -212,6 +212,7 @@ void bss_flush(struct wlantest *wt);
|
||||||
int bss_add_pmk_from_passphrase(struct wlantest_bss *bss,
|
int bss_add_pmk_from_passphrase(struct wlantest_bss *bss,
|
||||||
const char *passphrase);
|
const char *passphrase);
|
||||||
void pmk_deinit(struct wlantest_pmk *pmk);
|
void pmk_deinit(struct wlantest_pmk *pmk);
|
||||||
|
void tdls_deinit(struct wlantest_tdls *tdls);
|
||||||
|
|
||||||
struct wlantest_sta * sta_find(struct wlantest_bss *bss, const u8 *addr);
|
struct wlantest_sta * sta_find(struct wlantest_bss *bss, const u8 *addr);
|
||||||
struct wlantest_sta * sta_get(struct wlantest_bss *bss, const u8 *addr);
|
struct wlantest_sta * sta_get(struct wlantest_bss *bss, const u8 *addr);
|
||||||
|
|
Loading…
Reference in a new issue