2012-06-12 07:51:44

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH v3 0/4] Support proactive PREQ mechanism in Mesh

These series of patches allow the support of proactive PREQ mechanism as defined in
Sec. 13.10.4.2 of IEEE Std. 802.11-2012 based on the setting of dot11MeshHWMPRootMode
as follow:

dot11MeshHWMPRootMode (2): Proactive PREQ no PREP
dot11MeshHWMPRootMode (3): Proactive PREQ with PREP

Proactive RANN is now supported if the dot11MeshHWMPRootMode is set as (4).

This v3 is modified according to Johannes's comments on v2.

Chun-Yeow Yeoh (4):
{nl,cfg,mac}80211: implement dot11MeshHWMProotInterval and
dot11MeshHWMPactivePathToRootTimeout
mac80211: implement the proactive PREQ generation
mac80211: implement the proactive PREP generation
mac80211: invoke the timer only with correct dot11MeshHWMPRootMode
value

include/linux/ieee80211.h | 39 ++++++++++++++++++++++++++
include/linux/nl80211.h | 9 ++++++
include/net/cfg80211.h | 9 ++++++
net/mac80211/cfg.c | 10 +++++-
net/mac80211/debugfs_netdev.c | 6 ++++
net/mac80211/mesh.c | 12 ++++++--
net/mac80211/mesh_hwmp.c | 61 +++++++++++++++++++++++++++++++++++++----
net/wireless/mesh.c | 4 +++
net/wireless/nl80211.c | 15 +++++++++-
9 files changed, 153 insertions(+), 12 deletions(-)



2012-06-13 10:29:13

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 0/4] Support proactive PREQ mechanism in Mesh

I was going to apply this now, but the patches don't apply because you
didn't rebase on top of the kernel-doc/coding-style fixes that I already
picked up, can you please do that?

johannes


2012-06-12 07:51:47

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH v3 1/4] {nl,cfg,mac}80211: implement dot11MeshHWMProotInterval and dot11MeshHWMPactivePathToRootTimeout

Add the mesh configuration parameters dot11MeshHWMProotInterval and
dot11MeshHWMPactivePathToRootTimeout to be used by proactive PREQ mechanism.

Signed-off-by: Chun-Yeow Yeoh <[email protected]>
---
v2: avoid renumbering the old command ids (Johannes)
v3: adhere the coding style and add kernel-doc (Johannes)

include/linux/nl80211.h | 9 +++++++++
include/net/cfg80211.h | 9 +++++++++
net/mac80211/cfg.c | 6 ++++++
net/mac80211/debugfs_netdev.c | 6 ++++++
net/wireless/mesh.c | 4 ++++
net/wireless/nl80211.c | 15 ++++++++++++++-
6 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 970afdf..a0af908 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -2162,6 +2162,13 @@ enum nl80211_mntr_flags {
*
* @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode.
*
+ * @NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT: The time (in TUs) for
+ * which mesh STAs receiving a proactive PREQ shall consider the forwarding
+ * information to the root mesh STA to be valid.
+ *
+ * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between
+ * proactive PREQs are transmitted.
+ *
* @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
*/
enum nl80211_meshconf_params {
@@ -2188,6 +2195,8 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_RSSI_THRESHOLD,
NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
NL80211_MESHCONF_HT_OPMODE,
+ NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
+ NL80211_MESHCONF_HWMP_ROOT_INTERVAL,

/* keep last */
__NL80211_MESHCONF_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7319f25..687be1e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -794,6 +794,13 @@ struct bss_parameters {
* struct mesh_config - 802.11s mesh configuration
*
* These parameters can be changed while the mesh is active.
+ *
+ * @dot11MeshHWMPactivePathToRootTimeout: The time (in TUs) for which mesh STAs
+ * receiving a proactive PREQ shall consider the forwarding information to
+ * the root mesh STA to be valid.
+ *
+ * @dot11MeshHWMProotInterval: The interval of time (in TUs) between proactive
+ * PREQs are transmitted.
*/
struct mesh_config {
/* Timeouts in ms */
@@ -827,6 +834,8 @@ struct mesh_config {
bool dot11MeshForwarding;
s32 rssi_threshold;
u16 ht_opmode;
+ u32 dot11MeshHWMPactivePathToRootTimeout;
+ u16 dot11MeshHWMProotInterval;
};

/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 498c94e..cc8a23e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1590,6 +1590,12 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode;
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
}
+ if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask))
+ conf->dot11MeshHWMPactivePathToRootTimeout =
+ nconf->dot11MeshHWMPactivePathToRootTimeout;
+ if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
+ conf->dot11MeshHWMProotInterval =
+ nconf->dot11MeshHWMProotInterval;
return 0;
}

diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index d4272ff..9eabfa5 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -510,6 +510,10 @@ IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout,
+ u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMProotInterval,
+ u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC);
#endif

#define DEBUGFS_ADD_MODE(name, mode) \
@@ -611,6 +615,8 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
MESHPARAMS_ADD(rssi_threshold);
MESHPARAMS_ADD(ht_opmode);
+ MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout);
+ MESHPARAMS_ADD(dot11MeshHWMProotInterval);
#undef MESHPARAMS_ADD
}
#endif
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index b44c736..2f141cf 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -14,6 +14,8 @@

#define MESH_PATH_TIMEOUT 5000
#define MESH_RANN_INTERVAL 5000
+#define MESH_PATH_TO_ROOT_TIMEOUT 6000
+#define MESH_ROOT_INTERVAL 5000

/*
* Minimum interval between two consecutive PREQs originated by the same
@@ -62,6 +64,8 @@ const struct mesh_config default_mesh_config = {
.dot11MeshForwarding = true,
.rssi_threshold = MESH_RSSI_THRESHOLD,
.ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED,
+ .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
+ .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
};

const struct mesh_setup default_mesh_setup = {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7ae54b8..98afac9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3469,7 +3469,11 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
cur_params.rssi_threshold) ||
nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
- cur_params.ht_opmode))
+ cur_params.ht_opmode) ||
+ 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))
goto nla_put_failure;
nla_nest_end(msg, pinfoattr);
genlmsg_end(msg, hdr);
@@ -3506,6 +3510,8 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
[NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
[NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32},
[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 },
};

static const struct nla_policy
@@ -3605,6 +3611,13 @@ do {\
mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode,
mask, NL80211_MESHCONF_HT_OPMODE, nla_get_u16);
+ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
+ mask,
+ NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
+ nla_get_u32);
+ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval,
+ mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
+ nla_get_u16);
if (mask_out)
*mask_out = mask;

--
1.7.0.4


2012-06-13 08:21:08

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 2/4] mac80211: implement the proactive PREQ generation

On Tue, 2012-06-12 at 15:50 +0800, Chun-Yeow Yeoh wrote:

> /**
> + * enum - mesh PREQ element flags

Please fix this -- it has to be

enum ieee80211_preq_flags - ...

I was going to fix it up for you, but there are a lot of instances here.

> +/**
> + * enum - mesh PREQ element per target flags
> + *
> + * @TO_FLAG: target only subfield
> + * @USN_FLAG: unknown target HWMP sequence number subfield
> + */
> +enum ieee80211_preq_target_flags {
> + TO_FLAG = 1<<0,
> + USN_FLAG = 1<<2,

Since this is a fairly generic header, maybe they should have some
prefixes, at least IEEE80211_ or maybe IEEE80211_PREQ_?

> +/**
> + * enum - root mesh STA mode identifier used by dot11MeshHWMPRootMode
> + *
> + * @IEEE80211_NO_ROOT: the mesh STA is not a root mesh STA (default)
> + * @IEEE80211_ROOT: the mesh STA is a root mesh STA if greater than this value
> + * @IEEE80211_PROACTIVE_PREQ_NO_PREP: the mesh STA is a root mesh STA supports
> + * the proactive PREQ with proactive PREP subfield set to 0
> + * @IEEE80211_PROACTIVE_PREQ_WITH_PREP: the mesh STA is a root mesh STA
> + * supports the proactive PREQ with proactive PREP subfield set to 1
> + * @IEEE80211_PROACTIVE_RANN: the mesh STA is a root mesh STA supports
> + * the proactive RANN
> + */
> +enum {

That enum probably needs a name for kernel-doc to work

> + IEEE80211_NO_ROOT = 0,

These should have more specific prefixes I think?

johannes


2012-06-12 07:51:55

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH v3 4/4] mac80211: invoke the timer only with correct dot11MeshHWMPRootMode value

mesh_path_root_timer is invoked once the dot11MeshHWMPRootMode is larger than 1. This patch
also adds the backward compatible to the previous setting on dot11MeshHWMPRootMode. If the
user configures as follow, it will still trigger the proactive RANN with Gate Announcement.

iw mesh0 set mesh_param mesh_hwmp_rootmode 1
iw mesh0 set mesh_param mesh_gate_announcements 1

similar to the following setting:

iw mesh0 set mesh_param mesh_hwmp_rootmode 4
iw mesh0 set mesh_param mesh_gate_announcements 1

Signed-off-by: Chun-Yeow Yeoh <[email protected]>
---
v2: use constant for dot11MeshHWMPRootMode assignment (Johannes)
v3: use constant for dot11MeshHWMPRootMode comparison (Johannes)

net/mac80211/cfg.c | 4 ++--
net/mac80211/mesh.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index cc8a23e..6b8d2df 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1564,8 +1564,8 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
* announcements, so require this ifmsh to also be a root node
* */
if (nconf->dot11MeshGateAnnouncementProtocol &&
- !conf->dot11MeshHWMPRootMode) {
- conf->dot11MeshHWMPRootMode = 1;
+ !(conf->dot11MeshHWMPRootMode > IEEE80211_ROOT)) {
+ conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN;
ieee80211_mesh_root_setup(ifmsh);
}
conf->dot11MeshGateAnnouncementProtocol =
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6bff3c4..527d60e 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -443,7 +443,7 @@ static void ieee80211_mesh_path_root_timer(unsigned long data)

void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
{
- if (ifmsh->mshcfg.dot11MeshHWMPRootMode)
+ if (ifmsh->mshcfg.dot11MeshHWMPRootMode > IEEE80211_ROOT)
set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
else {
clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
--
1.7.0.4


2012-06-12 07:51:52

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH v3 3/4] mac80211: implement the proactive PREP generation

Generate the proactive PREP element in Proactive PREQ mode as defined in
Sec. 13.10.10.3 (Case D) of IEEE Std. 802.11-2012.

Signed-off-by: Chun-Yeow Yeoh <[email protected]>
---
v2: adhere to Linux kernel coding style (Johannes)
v3: eliminate 4 spaces indentation (Johannes)

net/mac80211/mesh_hwmp.c | 35 ++++++++++++++++++++++++++++++++---
1 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 3ce131b..1d2a122 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -519,10 +519,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
struct mesh_path *mpath = NULL;
u8 *target_addr, *orig_addr;
const u8 *da;
- u8 target_flags, ttl;
- u32 orig_sn, target_sn, lifetime;
+ u8 target_flags, ttl, flags;
+ u32 orig_sn, target_sn, lifetime, orig_metric;
bool reply = false;
bool forward = true;
+ bool root_is_gate;

/* Update target SN, if present */
target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
@@ -530,6 +531,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
target_sn = PREQ_IE_TARGET_SN(preq_elem);
orig_sn = PREQ_IE_ORIG_SN(preq_elem);
target_flags = PREQ_IE_TARGET_F(preq_elem);
+ orig_metric = metric;
+ /* Proactive PREQ gate announcements */
+ flags = PREQ_IE_FLAGS(preq_elem);
+ root_is_gate = !!(flags & RANN_FLAG_IS_GATE);

mhwmp_dbg("received PREQ from %pM", orig_addr);

@@ -544,6 +549,22 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
target_sn = ++ifmsh->sn;
ifmsh->last_sn_update = jiffies;
}
+ } else if (is_broadcast_ether_addr(target_addr) &&
+ (target_flags & TO_FLAG)) {
+ rcu_read_lock();
+ mpath = mesh_path_lookup(orig_addr, sdata);
+ if (mpath) {
+ if (flags & PROACTIVE_PREP_FLAG) {
+ reply = true;
+ target_addr = sdata->vif.addr;
+ target_sn = ++ifmsh->sn;
+ metric = 0;
+ ifmsh->last_sn_update = jiffies;
+ }
+ if (root_is_gate)
+ mesh_path_add_gate(mpath);
+ }
+ rcu_read_unlock();
} else {
rcu_read_lock();
mpath = mesh_path_lookup(target_addr, sdata);
@@ -576,8 +597,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
cpu_to_le32(lifetime), cpu_to_le32(metric),
0, sdata);
- } else
+ } else {
ifmsh->mshstats.dropped_frames_ttl++;
+ }
}

if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
@@ -597,6 +619,13 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
da = (mpath && mpath->is_root) ?
mpath->rann_snd_addr : broadcast_addr;
+
+ if (flags & PROACTIVE_PREP_FLAG) {
+ target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
+ target_sn = PREQ_IE_TARGET_SN(preq_elem);
+ metric = orig_metric;
+ }
+
mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
cpu_to_le32(orig_sn), target_flags, target_addr,
cpu_to_le32(target_sn), da,
--
1.7.0.4


2012-06-12 07:51:49

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH v3 2/4] mac80211: implement the proactive PREQ generation

Generate the proactive PREQ element as defined in Sec. 13.10.9.3 (Case C) of IEEE Std. 802.11-2012
based on the selection of dot11MeshHWMPRootMode as follow:
dot11MeshHWMPRootMode (2) is proactivePREQnoPREP
dot11MeshHWMPRootMode (3) is proactivePREQwithPREP

The proactive PREQ is generated based on the interval defined by dot11MeshHWMProotInterval.

With this change, proactive RANN element is now generated if the dot11MeshHWMPRootMode is set to
(4) instead of (1).

Signed-off-by: Chun-Yeow Yeoh <[email protected]>
---
v2: redefine the root mesh STA mode identifier (Johannes)
v3: redefine PREQ flag and target flag identifier (Johannes)

include/linux/ieee80211.h | 39 +++++++++++++++++++++++++++++++++++++++
net/mac80211/mesh.c | 10 ++++++++--
net/mac80211/mesh_hwmp.c | 26 +++++++++++++++++++++++---
3 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index ce9af89..beedec8 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -568,6 +568,26 @@ struct ieee80211s_hdr {
#define MESH_FLAGS_PS_DEEP 0x4

/**
+ * enum - mesh PREQ element flags
+ *
+ * @PROACTIVE_PREP_FLAG: proactive PREP subfield
+ */
+enum ieee80211_preq_flags {
+ PROACTIVE_PREP_FLAG = 1<<2,
+};
+
+/**
+ * enum - mesh PREQ element per target flags
+ *
+ * @TO_FLAG: target only subfield
+ * @USN_FLAG: unknown target HWMP sequence number subfield
+ */
+enum ieee80211_preq_target_flags {
+ TO_FLAG = 1<<0,
+ USN_FLAG = 1<<2,
+};
+
+/**
* struct ieee80211_quiet_ie
*
* This structure refers to "Quiet information element"
@@ -1474,6 +1494,25 @@ enum {
IEEE80211_PATH_METRIC_VENDOR = 255,
};

+/**
+ * enum - root mesh STA mode identifier used by dot11MeshHWMPRootMode
+ *
+ * @IEEE80211_NO_ROOT: the mesh STA is not a root mesh STA (default)
+ * @IEEE80211_ROOT: the mesh STA is a root mesh STA if greater than this value
+ * @IEEE80211_PROACTIVE_PREQ_NO_PREP: the mesh STA is a root mesh STA supports
+ * the proactive PREQ with proactive PREP subfield set to 0
+ * @IEEE80211_PROACTIVE_PREQ_WITH_PREP: the mesh STA is a root mesh STA
+ * supports the proactive PREQ with proactive PREP subfield set to 1
+ * @IEEE80211_PROACTIVE_RANN: the mesh STA is a root mesh STA supports
+ * the proactive RANN
+ */
+enum {
+ IEEE80211_NO_ROOT = 0,
+ IEEE80211_ROOT = 1,
+ IEEE80211_PROACTIVE_PREQ_NO_PREP = 2,
+ IEEE80211_PROACTIVE_PREQ_WITH_PREP = 3,
+ IEEE80211_PROACTIVE_RANN = 4,
+};

/*
* IEEE 802.11-2007 7.3.2.9 Country information element
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 7cf1950..6bff3c4 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -541,11 +541,17 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ u32 interval;

mesh_path_tx_root_frame(sdata);
+
+ if (ifmsh->mshcfg.dot11MeshHWMPRootMode == IEEE80211_PROACTIVE_RANN)
+ interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
+ else
+ interval = ifmsh->mshcfg.dot11MeshHWMProotInterval;
+
mod_timer(&ifmsh->mesh_path_root_timer,
- round_jiffies(TU_TO_EXP_TIME(
- ifmsh->mshcfg.dot11MeshHWMPRannInterval)));
+ round_jiffies(TU_TO_EXP_TIME(interval)));
}

#ifdef CONFIG_PM
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index fa7c580..3ce131b 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1157,13 +1157,33 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
- u8 flags;
+ u8 flags, target_flags = 0;

flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol)
? RANN_FLAG_IS_GATE : 0;
- mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
+
+ switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) {
+ case IEEE80211_PROACTIVE_RANN:
+ mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
cpu_to_le32(++ifmsh->sn),
0, NULL, 0, broadcast_addr,
- 0, sdata->u.mesh.mshcfg.element_ttl,
+ 0, ifmsh->mshcfg.element_ttl,
cpu_to_le32(interval), 0, 0, sdata);
+ break;
+ case IEEE80211_PROACTIVE_PREQ_WITH_PREP:
+ flags |= PROACTIVE_PREP_FLAG;
+ case IEEE80211_PROACTIVE_PREQ_NO_PREP:
+ interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout;
+ target_flags |= TO_FLAG | USN_FLAG;
+ mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr,
+ cpu_to_le32(++ifmsh->sn), target_flags,
+ (u8 *) broadcast_addr, 0, broadcast_addr,
+ 0, ifmsh->mshcfg.element_ttl,
+ cpu_to_le32(interval),
+ 0, cpu_to_le32(ifmsh->preq_id++), sdata);
+ break;
+ default:
+ mhwmp_dbg("Proactive mechanism not supported");
+ return;
+ }
}
--
1.7.0.4