diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 2c0c68505..b8a7c5190 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1040,6 +1040,7 @@ struct wpa_driver_mesh_bss_params { * See NL80211_MESHCONF_* for all the mesh config parameters. */ unsigned int flags; + int peer_link_timeout; }; struct wpa_driver_mesh_join_params { diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index e278c87a5..b6e5ff4e4 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -7821,6 +7821,7 @@ wpa_driver_nl80211_join_mesh(void *priv, struct nl_msg *msg; struct nlattr *container; int ret = 0; + u32 timeout; wpa_printf(MSG_DEBUG, "nl80211: mesh join (ifindex=%d)", drv->ifindex); msg = nl80211_drv_msg(drv, 0, NL80211_CMD_JOIN_MESH); @@ -7868,6 +7869,22 @@ wpa_driver_nl80211_join_mesh(void *priv, nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS, params->max_peer_links)) goto fail; + + /* + * Set NL80211_MESHCONF_PLINK_TIMEOUT even if user mpm is used because + * the timer could disconnect stations even in that case. + * + * Set 0xffffffff instead of 0 because NL80211_MESHCONF_PLINK_TIMEOUT + * does not allow 0. + */ + timeout = params->conf.peer_link_timeout; + if ((params->flags & WPA_DRIVER_MESH_FLAG_USER_MPM) || timeout == 0) + timeout = 0xffffffff; + if (nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT, timeout)) { + wpa_printf(MSG_ERROR, "nl80211: Failed to set PLINK_TIMEOUT"); + goto fail; + } + nla_nest_end(msg, container); ret = send_and_recv_msgs(drv, msg, NULL, NULL); diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index c3896239f..1ccae0b38 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -3476,6 +3476,7 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface, config->ap_scan = DEFAULT_AP_SCAN; config->user_mpm = DEFAULT_USER_MPM; config->max_peer_links = DEFAULT_MAX_PEER_LINKS; + config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY; config->fast_reauth = DEFAULT_FAST_REAUTH; config->p2p_go_intent = DEFAULT_P2P_GO_INTENT; config->p2p_intra_bss = DEFAULT_P2P_INTRA_BSS; @@ -4026,6 +4027,7 @@ static const struct global_parse_data global_fields[] = { #ifdef CONFIG_MESH { INT(user_mpm), 0 }, { INT_RANGE(max_peer_links, 0, 255), 0 }, + { INT(mesh_max_inactivity), 0 }, #endif /* CONFIG_MESH */ { INT(disable_scan_offload), 0 }, { INT(fast_reauth), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index be82c3c97..eeb4ba7f8 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -17,6 +17,7 @@ #endif /* CONFIG_NO_SCAN_PROCESSING */ #define DEFAULT_USER_MPM 1 #define DEFAULT_MAX_PEER_LINKS 99 +#define DEFAULT_MESH_MAX_INACTIVITY 300 #define DEFAULT_FAST_REAUTH 1 #define DEFAULT_P2P_GO_INTENT 7 #define DEFAULT_P2P_INTRA_BSS 1 @@ -1128,6 +1129,14 @@ struct wpa_config { * its certificate chain are included in EAP peer certificate events. */ int cert_in_cb; + + /** + * mesh_max_inactivity - Timeout in seconds to detect STA inactivity + * + * This timeout value is used in mesh STA to clean up inactive stations. + * By default: 300 seconds. + */ + int mesh_max_inactivity; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index ce5c2eba0..9c9685a7d 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1223,6 +1223,10 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->cert_in_cb != DEFAULT_CERT_IN_CB) fprintf(f, "cert_in_cb=%d\n", config->cert_in_cb); + + if (config->mesh_max_inactivity != DEFAULT_MESH_MAX_INACTIVITY) + fprintf(f, "mesh_max_inactivity=%d\n", + config->mesh_max_inactivity); } #endif /* CONFIG_NO_CONFIG_WRITE */ diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c index 5fdf4e085..32506b677 100644 --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -166,6 +166,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, bss->conf = *conf->bss; bss->conf->start_disabled = 1; bss->conf->mesh = MESH_ENABLED; + bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity; bss->iconf = conf; ifmsh->conf = conf; @@ -339,6 +340,7 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, params.flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM; params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS; } + params.conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity; if (wpa_supplicant_mesh_init(wpa_s, ssid)) { wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh"); diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index e56257818..23c229980 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -127,6 +127,11 @@ ap_scan=1 # Maximum number of mesh peering currently maintained by the STA. #max_peer_links=99 +# Timeout in seconds to detect STA inactivity (default: 300 seconds) +# +# This timeout value is used in mesh STA to clean up inactive stations. +#mesh_max_inactivity=300 + # cert_in_cb - Whether to include a peer certificate dump in events # This controls whether peer certificates for authentication server and # its certificate chain are included in EAP peer certificate events. This is