From 0cb5f8d94536e097af7a11273f79239001a602d6 Mon Sep 17 00:00:00 2001 From: Masashi Honma Date: Wed, 4 Feb 2015 11:26:51 +0900 Subject: [PATCH] mesh: Fix inactivity timer for 32 bit system Commit 5a2a6de6a5fec58dcfdb4320e4ec2b69d183a4c1 ('mesh: Make inactivity timer configurable') has a problem on 32 bit systems. Setting NL80211_MESHCONF_PLINK_TIMEOUT to 0xffffffff causes expiration of STA in a minute by NL80211_CMD_DEL_STATION event. this is the kernel rule for STA expiration: (current jiffies) > (frame Rx jiffies + NL80211_MESHCONF_PLINK_TIMEOUT * 250) On a 32 bit system, the right side could overflow and be unexpected small value if NL80211_MESHCONF_PLINK_TIMEOUT is sufficiently large. STA expiration occurs by this reason. This patch solves the problem by disabling the STA expiration functionality in mac80211. However, old kernel does not support disabling it. If so, this patch sets mac80211 inactivity timer 60 seconds into future from the wpa_supplicant inactivity timer. And I mis-understood that mesh_max_inactivity=0 disables inactivity timer in wpa_supplicant. This commit fixes it also. Signed-off-by: Masashi Honma --- src/drivers/driver_nl80211.c | 45 +++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index d681ea637..7785fbcaf 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -7849,16 +7849,13 @@ static int nl80211_put_mesh_id(struct nl_msg *msg, const u8 *mesh_id, } -static int -wpa_driver_nl80211_join_mesh(void *priv, +static int nl80211_join_mesh(struct i802_bss *bss, struct wpa_driver_mesh_join_params *params) { - struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; struct nl_msg *msg; struct nlattr *container; int ret = -1; - u32 timeout; wpa_printf(MSG_DEBUG, "nl80211: mesh join (ifindex=%d)", drv->ifindex); msg = nl80211_drv_msg(drv, 0, NL80211_CMD_JOIN_MESH); @@ -7910,14 +7907,9 @@ wpa_driver_nl80211_join_mesh(void *priv, /* * 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)) { + if (nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT, + params->conf.peer_link_timeout)) { wpa_printf(MSG_ERROR, "nl80211: Failed to set PLINK_TIMEOUT"); goto fail; } @@ -7941,6 +7933,37 @@ fail: } +static int +wpa_driver_nl80211_join_mesh(void *priv, + struct wpa_driver_mesh_join_params *params) +{ + struct i802_bss *bss = priv; + int ret, timeout; + + timeout = params->conf.peer_link_timeout; + + /* Disable kernel inactivity timer */ + if (params->flags & WPA_DRIVER_MESH_FLAG_USER_MPM) + params->conf.peer_link_timeout = 0; + + ret = nl80211_join_mesh(bss, params); + if (ret == -EINVAL && params->conf.peer_link_timeout == 0) { + wpa_printf(MSG_DEBUG, + "nl80211: Mesh join retry for peer_link_timeout"); + /* + * Old kernel does not support setting + * NL80211_MESHCONF_PLINK_TIMEOUT to zero, so set 60 seconds + * into future from peer_link_timeout. + */ + params->conf.peer_link_timeout = timeout + 60; + ret = nl80211_join_mesh(priv, params); + } + + params->conf.peer_link_timeout = timeout; + return ret; +} + + static int wpa_driver_nl80211_leave_mesh(void *priv) { struct i802_bss *bss = priv;