[PATCH] mesh: Fix inactivity timer for 32 bit system

Masashi Honma masashi.honma at gmail.com
Tue Feb 3 21:26:51 EST 2015


commit 5a2a6de6a5fec58dcfdb4320e4ec2b69d183a4c1 has problem on 32bit system.
Setting 0xffffffff to NL80211_MESHCONF_PLINK_TIMEOUT causes expiration of STA in
a minutes by NL80211_CMD_DEL_STATION event. To explain the reason, I will show
STA expiration rule in kernel. This is the expression.

(current jiffies) > (frame Rx jiffies + NL80211_MESHCONF_PLINK_TIMEOUT * 250)

On 32bit system, right side could be over flow 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. But old kernel does not support to disable it. If so, this patch sets
60 sec future to mac80211 inactivity timer than wpa_supplicant inactivity timer.

And I mis-understood that mesh_max_inactivity=0 disables inactivity timer in
wpa_supplicant. This patch fixes it also.

Signed-off-by: Masashi Honma <masashi.honma at gmail.com>
---
 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 d681ea6..db54c8b 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -7850,15 +7850,14 @@ static int nl80211_put_mesh_id(struct nl_msg *msg, const u8 *mesh_id,
 
 
 static int
-wpa_driver_nl80211_join_mesh(void *priv,
-			     struct wpa_driver_mesh_join_params *params)
+wpa_driver_nl80211_join_mesh2(void *priv,
+			      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);
@@ -7907,17 +7906,12 @@ wpa_driver_nl80211_join_mesh(void *priv,
 			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)) {
+	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 +7935,35 @@ fail:
 }
 
 
+static int
+wpa_driver_nl80211_join_mesh(void *priv,
+			     struct wpa_driver_mesh_join_params *params)
+{
+	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 = wpa_driver_nl80211_join_mesh2(priv, 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 to set zero to
+		 * NL80211_MESHCONF_PLINK_TIMEOUT.
+		 * So set 60 sec future than peer_link_timeout.
+		 */
+		params->conf.peer_link_timeout = timeout + 60;
+		ret = wpa_driver_nl80211_join_mesh2(priv, params);
+	}
+
+	params->conf.peer_link_timeout = timeout;
+	return ret;
+}
+
+
 static int wpa_driver_nl80211_leave_mesh(void *priv)
 {
 	struct i802_bss *bss = priv;
-- 
2.1.0



More information about the HostAP mailing list