{nl,cfg,mac}80211: implement dot11MeshHWMPconfirmationInterval
authorChun-Yeow Yeoh <yeohchunyeow@gmail.com>
Wed, 13 Jun 2012 18:06:10 +0000 (02:06 +0800)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 18 Jun 2012 11:55:15 +0000 (13:55 +0200)
As defined in section 13.10.9.3 Case D (802.11-2012), this
control variable is used to limit the mesh STA to send only
one PREQ to a root mesh STA within this interval of time
(in TUs). The default value for this variable is set to
2000 TUs. However, for current implementation, the maximum
configurable of dot11MeshHWMPconfirmationInterval is
restricted by dot11MeshHWMPactivePathTimeout.

Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@gmail.com>
[line-break commit log]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/linux/nl80211.h
include/net/cfg80211.h
net/mac80211/cfg.c
net/mac80211/debugfs_netdev.c
net/mac80211/mesh.h
net/mac80211/mesh_hwmp.c
net/wireless/mesh.c
net/wireless/nl80211.c

index 6936fabe87976e60240794444f98452fb7829054..b7c3b737ddde37002bdc12da6acd975720c4fb72 100644 (file)
@@ -2192,6 +2192,10 @@ enum nl80211_mntr_flags {
  * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between
  *     proactive PREQs are transmitted.
  *
+ * @NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL: The minimum interval of time
+ *     (in TUs) during which a mesh STA can send only one Action frame
+ *     containing a PREQ element for root path confirmation.
+ *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
  */
 enum nl80211_meshconf_params {
@@ -2220,6 +2224,7 @@ enum nl80211_meshconf_params {
        NL80211_MESHCONF_HT_OPMODE,
        NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
        NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
+       NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
 
        /* keep last */
        __NL80211_MESHCONF_ATTR_AFTER_LAST,
index e52b38d7b1b6616fa10117fabb23f647767e87e0..f0163a10b8ce819188720e70229a6ab1a63c3aa8 100644 (file)
@@ -849,6 +849,9 @@ struct bss_parameters {
  *
  * @dot11MeshHWMProotInterval: The interval of time (in TUs) between proactive
  *     PREQs are transmitted.
+ * @dot11MeshHWMPconfirmationInterval: The minimum interval of time (in TUs)
+ *     during which a mesh STA can send only one Action frame containing
+ *     a PREQ element for root path confirmation.
  */
 struct mesh_config {
        u16 dot11MeshRetryTimeout;
@@ -875,6 +878,7 @@ struct mesh_config {
        u16 ht_opmode;
        u32 dot11MeshHWMPactivePathToRootTimeout;
        u16 dot11MeshHWMProotInterval;
+       u16 dot11MeshHWMPconfirmationInterval;
 };
 
 /**
index 5bd316c0a63db3cadde6ae6c36321f0277ba5c23..6e25ac4873c70b3dc5fc9b2641a60e0974f402a6 100644 (file)
@@ -1596,6 +1596,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
        if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
                conf->dot11MeshHWMProotInterval =
                        nconf->dot11MeshHWMProotInterval;
+       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask))
+               conf->dot11MeshHWMPconfirmationInterval =
+                       nconf->dot11MeshHWMPconfirmationInterval;
        return 0;
 }
 
index a8cea70902e42efdc4c0f181b0ad9098e77086bc..512c894893d62a86cc11f8dca368836052abb883 100644 (file)
@@ -514,6 +514,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout,
                  u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC);
 IEEE80211_IF_FILE(dot11MeshHWMProotInterval,
                  u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,
+                 u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval, DEC);
 #endif
 
 #define DEBUGFS_ADD_MODE(name, mode) \
@@ -617,6 +619,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
        MESHPARAMS_ADD(ht_opmode);
        MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout);
        MESHPARAMS_ADD(dot11MeshHWMProotInterval);
+       MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval);
 #undef MESHPARAMS_ADD
 }
 #endif
index c7400a23b64b286d52c288a003c6670a577587f4..faaa39bcfd109b783c2f297fdda6aa3585587026 100644 (file)
@@ -104,6 +104,7 @@ enum mesh_deferred_task_flags {
  * an mpath to a hash bucket on a path table.
  * @rann_snd_addr: the RANN sender address
  * @rann_metric: the aggregated path metric towards the root node
+ * @last_preq_to_root: Timestamp of last PREQ sent to root
  * @is_root: the destination station of this path is a root node
  * @is_gate: the destination station of this path is a mesh gate
  *
@@ -131,6 +132,7 @@ struct mesh_path {
        spinlock_t state_lock;
        u8 rann_snd_addr[ETH_ALEN];
        u32 rann_metric;
+       unsigned long last_preq_to_root;
        bool is_root;
        bool is_gate;
 };
index 35e3acbe22624f3874f3cfbde8741dcbb9a40bc3..bea52479e3aafb03aacc18fd96088b7209c1aaff 100644 (file)
@@ -98,6 +98,8 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae)
 #define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries)
 #define disc_timeout_jiff(s) \
        msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout)
+#define root_path_confirmation_jiffies(s) \
+       msecs_to_jiffies(sdata->u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval)
 
 enum mpath_frame_type {
        MPATH_PREQ = 0,
@@ -811,11 +813,14 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
        }
 
        if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
-            time_after(jiffies, mpath->exp_time - 1*HZ)) &&
+            (time_after(jiffies, mpath->last_preq_to_root +
+                                 root_path_confirmation_jiffies(sdata)) ||
+            time_before(jiffies, mpath->last_preq_to_root))) &&
             !(mpath->flags & MESH_PATH_FIXED)) {
                mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name,
                                                               orig_addr);
                mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
+               mpath->last_preq_to_root = jiffies;
        }
 
        if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn &&
index 2f141cfd581e85698e12ddfc521a485f8e446c43..3b73b07486cfb34197f653f1e4896e1cb56c6173 100644 (file)
@@ -16,6 +16,7 @@
 #define MESH_RANN_INTERVAL      5000
 #define MESH_PATH_TO_ROOT_TIMEOUT      6000
 #define MESH_ROOT_INTERVAL     5000
+#define MESH_ROOT_CONFIRMATION_INTERVAL 2000
 
 /*
  * Minimum interval between two consecutive PREQs originated by the same
@@ -66,6 +67,7 @@ const struct mesh_config default_mesh_config = {
        .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED,
        .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
        .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
+       .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
 };
 
 const struct mesh_setup default_mesh_setup = {
index f8930db613df54327049b9098957c4d721ce612d..a363ca17bfc572d81bb115da5d302416740bca93 100644 (file)
@@ -3473,7 +3473,9 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
            nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
                        cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
            nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
-                       cur_params.dot11MeshHWMProotInterval))
+                       cur_params.dot11MeshHWMProotInterval) ||
+           nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
+                       cur_params.dot11MeshHWMPconfirmationInterval))
                goto nla_put_failure;
        nla_nest_end(msg, pinfoattr);
        genlmsg_end(msg, hdr);
@@ -3511,6 +3513,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
        [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
        [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
        [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
 };
 
 static const struct nla_policy
@@ -3625,6 +3628,10 @@ do {\
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval,
                                  mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
                                  nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
+                                 dot11MeshHWMPconfirmationInterval, mask,
+                                 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
+                                 nla_get_u16);
        if (mask_out)
                *mask_out = mask;