Commit dca7e943 authored by Thomas Pedersen's avatar Thomas Pedersen Committed by John W. Linville

{nl,cfg,mac}80211: implement dot11MeshHWMPperrMinInterval

As per 802.11mb 13.9.11.3
Signed-off-by: default avatarThomas Pedersen <thomas@cozybit.com>
Signed-off-by: default avatarJavier Cardona <javier@cozybit.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent d3c1597b
...@@ -2094,6 +2094,10 @@ enum nl80211_mntr_flags { ...@@ -2094,6 +2094,10 @@ enum nl80211_mntr_flags {
* access to a broader network beyond the MBSS. This is done via Root * access to a broader network beyond the MBSS. This is done via Root
* Announcement frames. * Announcement frames.
* *
* @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in
* TUs) during which a mesh STA can send only one Action frame containing a
* PERR element.
*
* @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
* *
* @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
...@@ -2117,6 +2121,7 @@ enum nl80211_meshconf_params { ...@@ -2117,6 +2121,7 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_ELEMENT_TTL, NL80211_MESHCONF_ELEMENT_TTL,
NL80211_MESHCONF_HWMP_RANN_INTERVAL, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
NL80211_MESHCONF_GATE_ANNOUNCEMENTS, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
/* keep last */ /* keep last */
__NL80211_MESHCONF_ATTR_AFTER_LAST, __NL80211_MESHCONF_ATTR_AFTER_LAST,
......
...@@ -782,6 +782,7 @@ struct mesh_config { ...@@ -782,6 +782,7 @@ struct mesh_config {
u16 min_discovery_timeout; u16 min_discovery_timeout;
u32 dot11MeshHWMPactivePathTimeout; u32 dot11MeshHWMPactivePathTimeout;
u16 dot11MeshHWMPpreqMinInterval; u16 dot11MeshHWMPpreqMinInterval;
u16 dot11MeshHWMPperrMinInterval;
u16 dot11MeshHWMPnetDiameterTraversalTime; u16 dot11MeshHWMPnetDiameterTraversalTime;
u8 dot11MeshHWMPRootMode; u8 dot11MeshHWMPRootMode;
u16 dot11MeshHWMPRannInterval; u16 dot11MeshHWMPRannInterval;
......
...@@ -1272,6 +1272,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, ...@@ -1272,6 +1272,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask)) if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
conf->dot11MeshHWMPpreqMinInterval = conf->dot11MeshHWMPpreqMinInterval =
nconf->dot11MeshHWMPpreqMinInterval; nconf->dot11MeshHWMPpreqMinInterval;
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, mask))
conf->dot11MeshHWMPperrMinInterval =
nconf->dot11MeshHWMPperrMinInterval;
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
mask)) mask))
conf->dot11MeshHWMPnetDiameterTraversalTime = conf->dot11MeshHWMPnetDiameterTraversalTime =
......
...@@ -405,6 +405,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout, ...@@ -405,6 +405,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval, IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval,
u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime, IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries, IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
...@@ -534,6 +536,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) ...@@ -534,6 +536,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
MESHPARAMS_ADD(dot11MeshMaxPeerLinks); MESHPARAMS_ADD(dot11MeshMaxPeerLinks);
MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout); MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout);
MESHPARAMS_ADD(dot11MeshHWMPpreqMinInterval); MESHPARAMS_ADD(dot11MeshHWMPpreqMinInterval);
MESHPARAMS_ADD(dot11MeshHWMPperrMinInterval);
MESHPARAMS_ADD(dot11MeshHWMPnetDiameterTraversalTime); MESHPARAMS_ADD(dot11MeshHWMPnetDiameterTraversalTime);
MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries); MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries);
MESHPARAMS_ADD(path_refresh_time); MESHPARAMS_ADD(path_refresh_time);
......
...@@ -514,7 +514,9 @@ struct ieee80211_if_mesh { ...@@ -514,7 +514,9 @@ struct ieee80211_if_mesh {
atomic_t mpaths; atomic_t mpaths;
/* Timestamp of last SN update */ /* Timestamp of last SN update */
unsigned long last_sn_update; unsigned long last_sn_update;
/* Timestamp of last SN sent */ /* Time when it's ok to send next PERR */
unsigned long next_perr;
/* Timestamp of last PREQ sent */
unsigned long last_preq; unsigned long last_preq;
struct mesh_rmc *rmc; struct mesh_rmc *rmc;
spinlock_t mesh_preq_queue_lock; spinlock_t mesh_preq_queue_lock;
......
...@@ -749,6 +749,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) ...@@ -749,6 +749,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
atomic_set(&ifmsh->mpaths, 0); atomic_set(&ifmsh->mpaths, 0);
mesh_rmc_init(sdata); mesh_rmc_init(sdata);
ifmsh->last_preq = jiffies; ifmsh->last_preq = jiffies;
ifmsh->next_perr = jiffies;
/* Allocate all mesh structures when creating the first mesh interface. */ /* Allocate all mesh structures when creating the first mesh interface. */
if (!mesh_allocated) if (!mesh_allocated)
ieee80211s_init(); ieee80211s_init();
......
...@@ -241,11 +241,15 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, ...@@ -241,11 +241,15 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
{ {
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_mgmt *mgmt; struct ieee80211_mgmt *mgmt;
u8 *pos, ie_len; u8 *pos, ie_len;
int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) + int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
sizeof(mgmt->u.action.u.mesh_action); sizeof(mgmt->u.action.u.mesh_action);
if (time_before(jiffies, ifmsh->next_perr))
return -EAGAIN;
skb = dev_alloc_skb(local->hw.extra_tx_headroom + skb = dev_alloc_skb(local->hw.extra_tx_headroom +
hdr_len + hdr_len +
2 + 15 /* PERR IE */); 2 + 15 /* PERR IE */);
...@@ -290,6 +294,8 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, ...@@ -290,6 +294,8 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
/* see note in function header */ /* see note in function header */
prepare_frame_for_deferred_tx(sdata, skb); prepare_frame_for_deferred_tx(sdata, skb);
ifmsh->next_perr = TU_TO_EXP_TIME(
ifmsh->mshcfg.dot11MeshHWMPperrMinInterval);
ieee80211_add_pending_skb(local, skb); ieee80211_add_pending_skb(local, skb);
return 0; return 0;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* interface * interface
*/ */
#define MESH_PREQ_MIN_INT 10 #define MESH_PREQ_MIN_INT 10
#define MESH_PERR_MIN_INT 100
#define MESH_DIAM_TRAVERSAL_TIME 50 #define MESH_DIAM_TRAVERSAL_TIME 50
/* /*
...@@ -47,6 +48,7 @@ const struct mesh_config default_mesh_config = { ...@@ -47,6 +48,7 @@ const struct mesh_config default_mesh_config = {
.dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS, .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS,
.dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT, .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT,
.dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT, .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT,
.dot11MeshHWMPperrMinInterval = MESH_PERR_MIN_INT,
.dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME, .dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME,
.dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES, .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES,
.path_refresh_time = MESH_PATH_REFRESH_TIME, .path_refresh_time = MESH_PATH_REFRESH_TIME,
......
...@@ -3195,6 +3195,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, ...@@ -3195,6 +3195,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
cur_params.dot11MeshHWMPactivePathTimeout); cur_params.dot11MeshHWMPactivePathTimeout);
NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
cur_params.dot11MeshHWMPpreqMinInterval); cur_params.dot11MeshHWMPpreqMinInterval);
NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
cur_params.dot11MeshHWMPperrMinInterval);
NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
cur_params.dot11MeshHWMPnetDiameterTraversalTime); cur_params.dot11MeshHWMPnetDiameterTraversalTime);
NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
...@@ -3229,6 +3231,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A ...@@ -3229,6 +3231,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
[NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 }, [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
[NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
[NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
[NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 },
[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
[NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 }, [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
[NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
...@@ -3303,6 +3306,9 @@ do {\ ...@@ -3303,6 +3306,9 @@ do {\
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
nla_get_u16); nla_get_u16);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
nla_get_u16);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
dot11MeshHWMPnetDiameterTraversalTime, dot11MeshHWMPnetDiameterTraversalTime,
mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment