diff --git a/src/drivers/driver.h b/src/drivers/driver.h index a30120123..40f1d0e3f 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -699,7 +699,9 @@ enum tdls_oper { TDLS_SETUP, TDLS_TEARDOWN, TDLS_ENABLE_LINK, - TDLS_DISABLE_LINK + TDLS_DISABLE_LINK, + TDLS_ENABLE, + TDLS_DISABLE }; /** diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 4ee363951..14c2b7b80 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -625,6 +625,9 @@ int wpa_tdls_recv_teardown_notify(struct wpa_sm *sm, const u8 *addr, u8 *rbuf, *pos; int ielen; + if (sm->tdls_disabled) + return -1; + /* Find the node and free from the list */ for (peer = sm->tdls; peer; peer = peer->next) { if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0) @@ -1825,6 +1828,9 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr) struct wpa_tdls_peer *peer; int tdls_prohibited = sm->tdls_prohibited; + if (sm->tdls_disabled) + return -1; + #ifdef CONFIG_TDLS_TESTING if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) && tdls_prohibited) { @@ -1869,6 +1875,9 @@ int wpa_tdls_reneg(struct wpa_sm *sm, const u8 *addr) { struct wpa_tdls_peer *peer; + if (sm->tdls_disabled) + return -1; + for (peer = sm->tdls; peer; peer = peer->next) { if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0) break; @@ -1895,6 +1904,11 @@ static void wpa_supplicant_rx_tdls(void *ctx, const u8 *src_addr, wpa_hexdump(MSG_DEBUG, "TDLS: Received Data frame encapsulation", buf, len); + if (sm->tdls_disabled) { + wpa_printf(MSG_DEBUG, "TDLS: Discard message - TDLS disabled"); + return; + } + if (os_memcmp(src_addr, sm->own_addr, ETH_ALEN) == 0) { wpa_printf(MSG_DEBUG, "TDLS: Discard copy of own message"); return; @@ -2051,3 +2065,10 @@ void wpa_tdls_assoc_resp_ies(struct wpa_sm *sm, const u8 *ies, size_t len) sm->tdls_prohibited = 1; } } + + +void wpa_tdls_enable(struct wpa_sm *sm, int enabled) +{ + wpa_printf(MSG_DEBUG, "TDLS: %s", enabled ? "enabled" : "disabled"); + sm->tdls_disabled = !enabled; +} diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 41bafee63..111597ca4 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -346,5 +346,6 @@ int wpa_tdls_recv_teardown_notify(struct wpa_sm *sm, const u8 *addr, u16 reason_code); int wpa_tdls_init(struct wpa_sm *sm); void wpa_tdls_deinit(struct wpa_sm *sm); +void wpa_tdls_enable(struct wpa_sm *sm, int enabled); #endif /* WPA_H */ diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 590dea149..09a2e4ff5 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -97,6 +97,7 @@ struct wpa_sm { #ifdef CONFIG_TDLS struct wpa_tdls_peer *tdls; int tdls_prohibited; + int tdls_disabled; #endif /* CONFIG_TDLS */ #ifdef CONFIG_IEEE80211R diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index cb813ba79..5488ea447 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -114,6 +114,17 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, tdls_testing = strtol(value, NULL, 0); wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing); #endif /* CONFIG_TDLS_TESTING */ +#ifdef CONFIG_TDLS + } else if (os_strcasecmp(cmd, "tdls_disabled") == 0) { + int disabled = atoi(value); + wpa_printf(MSG_DEBUG, "TDLS: tdls_disabled=%d", disabled); + if (disabled) { + if (wpa_drv_tdls_oper(wpa_s, TDLS_DISABLE, NULL) < 0) + ret = -1; + } else if (wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL) < 0) + ret = -1; + wpa_tdls_enable(wpa_s->wpa, !disabled); +#endif /* CONFIG_TDLS */ } else { value[-1] = '='; ret = wpa_config_process_global(wpa_s->conf, cmd, -1);