2012-06-06 10:21:00

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH 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).

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/nl80211.h | 9 +++++
include/net/cfg80211.h | 2 +
net/mac80211/cfg.c | 12 ++++++-
net/mac80211/debugfs_netdev.c | 6 +++
net/mac80211/mesh.c | 9 +++--
net/mac80211/mesh_hwmp.c | 72 +++++++++++++++++++++++++++++++++++------
net/wireless/mesh.c | 4 ++
net/wireless/nl80211.c | 14 ++++++++
8 files changed, 113 insertions(+), 15 deletions(-)



2012-06-06 10:23:33

by Johannes Berg

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

On Wed, 2012-06-06 at 18:20 +0800, Chun-Yeow Yeoh wrote:

> @@ -2175,11 +2182,13 @@ enum nl80211_meshconf_params {
> NL80211_MESHCONF_PATH_REFRESH_TIME,
> NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
> NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
> + NL80211_MESHCONF_HWMP_ACTIVE_PATH_TO_ROOT_TIMEOUT,
> NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
> NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
> NL80211_MESHCONF_HWMP_ROOTMODE,
> NL80211_MESHCONF_ELEMENT_TTL,
> NL80211_MESHCONF_HWMP_RANN_INTERVAL,
> + NL80211_MESHCONF_HWMP_ROOT_INTERVAL,

Heh, no, you can't do this.

johannes


2012-06-06 10:26:11

by Johannes Berg

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

On Wed, 2012-06-06 at 18:20 +0800, Chun-Yeow Yeoh wrote:

> - !conf->dot11MeshHWMPRootMode) {
> - conf->dot11MeshHWMPRootMode = 1;
> + !(conf->dot11MeshHWMPRootMode > 1)) {
> + conf->dot11MeshHWMPRootMode = 4;

if you have constants, why not use them?

johannes


2012-06-06 10:21:03

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH 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]>
---
include/linux/nl80211.h | 9 +++++++++
include/net/cfg80211.h | 2 ++
net/mac80211/cfg.c | 8 ++++++++
net/mac80211/debugfs_netdev.c | 6 ++++++
net/wireless/mesh.c | 4 ++++
net/wireless/nl80211.c | 14 ++++++++++++++
6 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 85e5037..1744a0a 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -2123,6 +2123,10 @@ enum nl80211_mntr_flags {
* points receiving a PREQ shall consider the forwarding information from the
* root to be valid. (TU = time unit)
*
+ * @NL80211_MESHCONF_HWMP_ACTIVE_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_PREQ_MIN_INTERVAL: The minimum interval of time (in
* TUs) during which an MP can send only one action frame containing a PREQ
* reference element
@@ -2138,6 +2142,9 @@ enum nl80211_mntr_flags {
* @NL80211_MESHCONF_HWMP_RANN_INTERVAL: The interval of time (in TUs) between
* root announcements are transmitted.
*
+ * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between
+ * proactive PREQs are transmitted.
+ *
* @NL80211_MESHCONF_GATE_ANNOUNCEMENTS: Advertise that this mesh station has
* access to a broader network beyond the MBSS. This is done via Root
* Announcement frames.
@@ -2175,11 +2182,13 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_PATH_REFRESH_TIME,
NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+ NL80211_MESHCONF_HWMP_ACTIVE_PATH_TO_ROOT_TIMEOUT,
NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
NL80211_MESHCONF_HWMP_ROOTMODE,
NL80211_MESHCONF_ELEMENT_TTL,
NL80211_MESHCONF_HWMP_RANN_INTERVAL,
+ NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
NL80211_MESHCONF_FORWARDING,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4c90c44..128cdeb 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -814,11 +814,13 @@ struct mesh_config {
u32 path_refresh_time;
u16 min_discovery_timeout;
u32 dot11MeshHWMPactivePathTimeout;
+ u32 dot11MeshHWMPactivePathToRootTimeout;
u16 dot11MeshHWMPpreqMinInterval;
u16 dot11MeshHWMPperrMinInterval;
u16 dot11MeshHWMPnetDiameterTraversalTime;
u8 dot11MeshHWMPRootMode;
u16 dot11MeshHWMPRannInterval;
+ u16 dot11MeshHWMProotInterval;
/* This is missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol
* set to true only means that the station will announce others it's a
* mesh gate, but not necessarily using the gate announcement protocol.
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 50aea1a..626baa2 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1538,6 +1538,10 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
conf->dot11MeshHWMPactivePathTimeout =
nconf->dot11MeshHWMPactivePathTimeout;
+ if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TO_ROOT_TIMEOUT,
+ mask))
+ conf->dot11MeshHWMPactivePathToRootTimeout =
+ nconf->dot11MeshHWMPactivePathToRootTimeout;
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
conf->dot11MeshHWMPpreqMinInterval =
nconf->dot11MeshHWMPpreqMinInterval;
@@ -1568,6 +1572,10 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
conf->dot11MeshHWMPRannInterval =
nconf->dot11MeshHWMPRannInterval;
}
+ if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask)) {
+ conf->dot11MeshHWMProotInterval =
+ nconf->dot11MeshHWMProotInterval;
+ }
if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 1a3b361..268ceb7 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -489,6 +489,8 @@ IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout,
+ u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval,
@@ -507,6 +509,8 @@ IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMProotInterval,
+ u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC);
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);
@@ -599,6 +603,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
MESHPARAMS_ADD(auto_open_plinks);
MESHPARAMS_ADD(dot11MeshMaxPeerLinks);
MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout);
+ MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout);
MESHPARAMS_ADD(dot11MeshHWMPpreqMinInterval);
MESHPARAMS_ADD(dot11MeshHWMPperrMinInterval);
MESHPARAMS_ADD(dot11MeshHWMPnetDiameterTraversalTime);
@@ -607,6 +612,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
MESHPARAMS_ADD(min_discovery_timeout);
MESHPARAMS_ADD(dot11MeshHWMPRootMode);
MESHPARAMS_ADD(dot11MeshHWMPRannInterval);
+ MESHPARAMS_ADD(dot11MeshHWMProotInterval);
MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
MESHPARAMS_ADD(rssi_threshold);
MESHPARAMS_ADD(ht_opmode);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 2e3b700..ad44e32 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -13,7 +13,9 @@
#define MESH_HOLD_T 100

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

/*
* Minimum interval between two consecutive PREQs originated by the same
@@ -51,6 +53,7 @@ const struct mesh_config default_mesh_config = {
.dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS,
.dot11MeshNbrOffsetMaxNeighbor = MESH_SYNC_NEIGHBOR_OFFSET_MAX,
.dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT,
+ .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
.dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT,
.dot11MeshHWMPperrMinInterval = MESH_PERR_MIN_INT,
.dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME,
@@ -58,6 +61,7 @@ const struct mesh_config default_mesh_config = {
.path_refresh_time = MESH_PATH_REFRESH_TIME,
.min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
.dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
+ .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
.dot11MeshGateAnnouncementProtocol = false,
.dot11MeshForwarding = true,
.rssi_threshold = MESH_RSSI_THRESHOLD,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b22f1f8..8af4561 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3449,6 +3449,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
cur_params.min_discovery_timeout) ||
nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
cur_params.dot11MeshHWMPactivePathTimeout) ||
+ nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TO_ROOT_TIMEOUT,
+ cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
cur_params.dot11MeshHWMPpreqMinInterval) ||
nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
@@ -3459,6 +3461,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
cur_params.dot11MeshHWMPRootMode) ||
nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
cur_params.dot11MeshHWMPRannInterval) ||
+ nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
+ cur_params.dot11MeshHWMProotInterval) ||
nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
cur_params.dot11MeshGateAnnouncementProtocol) ||
nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
@@ -3494,11 +3498,14 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
[NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
[NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
[NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
+ [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TO_ROOT_TIMEOUT]
+ = { .type = NLA_U32 },
[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_ROOTMODE] = { .type = NLA_U8 },
[NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
+ [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
[NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
[NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
[NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32},
@@ -3574,6 +3581,9 @@ do {\
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
nla_get_u32);
+ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
+ mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TO_ROOT_TIMEOUT,
+ nla_get_u32);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
nla_get_u16);
@@ -3593,6 +3603,10 @@ do {\
NL80211_MESHCONF_HWMP_RANN_INTERVAL,
nla_get_u16);
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,
dot11MeshGateAnnouncementProtocol, mask,
NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
nla_get_u8);
--
1.7.0.4


2012-06-06 10:25:07

by Johannes Berg

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


> + } else if (is_broadcast_ether_addr(target_addr) &&
> + (target_flags & MP_F_DO)) {

please indent to below is_

> + mpath = mesh_path_lookup(orig_addr, sdata);
> + if (mpath) {
> + if (flags & PREQ_F_PREP)
> + reply = true;
> + if (root_is_gate)
> + mesh_path_add_gate(mpath);
> + }
> } else {
> rcu_read_lock();
> mpath = mesh_path_lookup(target_addr, sdata);
> @@ -581,11 +594,20 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
> ttl = ifmsh->mshcfg.element_ttl;
> if (ttl != 0) {
> mhwmp_dbg("replying to the PREQ");
> - mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
> - cpu_to_le32(orig_sn), 0, target_addr,
> - cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
> - cpu_to_le32(lifetime), cpu_to_le32(metric),
> - 0, sdata);
> + if (!is_broadcast_ether_addr(target_addr))
> + mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
> + cpu_to_le32(orig_sn), 0, target_addr,
> + cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
> + cpu_to_le32(lifetime), cpu_to_le32(metric),
> + 0, sdata);
> + else {

please put braces around all pieces of an if/else if on one branch

Maybe you should run checkpatch :-)

johannes


2012-06-06 10:21:11

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH 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]>
---
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 626baa2..31ffab1 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1561,8 +1561,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 > 1)) {
+ conf->dot11MeshHWMPRootMode = 4;
ieee80211_mesh_root_setup(ifmsh);
}
conf->dot11MeshGateAnnouncementProtocol =
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 5e19e0d..5b42598 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 > 1)
set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
else {
clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
--
1.7.0.4


2012-06-06 10:25:55

by Johannes Berg

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

On Wed, 2012-06-06 at 18:20 +0800, Chun-Yeow Yeoh wrote:

> +enum mesh_hwmp_rootmode {
> + noRoot = 0,
> + notavailable,
> + proactivePREQnoPREP,
> + proactivePREQwithPREP,
> + rann
> +};

this hsould probably also be in nl80211 or ieee80211 and have validation
in nl80211 etc. since it comes from userspace

johannes


2012-06-06 10:21:08

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH 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]>
---
net/mac80211/mesh_hwmp.c | 34 ++++++++++++++++++++++++++++------
1 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index b1e4399..d038767 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -529,10 +529,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;
+ u8 target_flags, ttl, flags;
u32 orig_sn, target_sn, lifetime;
bool reply = false;
bool forward = true;
+ bool root_is_gate;

/* Update target SN, if present */
target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
@@ -540,6 +541,9 @@ 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);
+ /* 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);

@@ -554,6 +558,15 @@ 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 & MP_F_DO)) {
+ mpath = mesh_path_lookup(orig_addr, sdata);
+ if (mpath) {
+ if (flags & PREQ_F_PREP)
+ reply = true;
+ if (root_is_gate)
+ mesh_path_add_gate(mpath);
+ }
} else {
rcu_read_lock();
mpath = mesh_path_lookup(target_addr, sdata);
@@ -581,11 +594,20 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
ttl = ifmsh->mshcfg.element_ttl;
if (ttl != 0) {
mhwmp_dbg("replying to the PREQ");
- mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
- cpu_to_le32(orig_sn), 0, target_addr,
- cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
- cpu_to_le32(lifetime), cpu_to_le32(metric),
- 0, sdata);
+ if (!is_broadcast_ether_addr(target_addr))
+ mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
+ cpu_to_le32(orig_sn), 0, target_addr,
+ cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
+ cpu_to_le32(lifetime), cpu_to_le32(metric),
+ 0, sdata);
+ else {
+ mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
+ cpu_to_le32(orig_sn), 0, sdata->vif.addr,
+ cpu_to_le32(++ifmsh->sn), mgmt->sa, 0, ttl,
+ cpu_to_le32(lifetime), 0,
+ 0, sdata);
+ ifmsh->last_sn_update = jiffies;
+ }
} else
ifmsh->mshstats.dropped_frames_ttl++;
}
--
1.7.0.4


2012-06-06 10:24:12

by Johannes Berg

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

On Wed, 2012-06-06 at 18:20 +0800, Chun-Yeow Yeoh wrote:

> +enum mesh_hwmp_rootmode {
> + noRoot = 0,
> + notavailable,
> + proactivePREQnoPREP,
> + proactivePREQwithPREP,
> + rann
> +};

Those are some ugly names .. I think they should have a prefix and be
less camel-case

johannes


2012-06-06 10:21:05

by Chun-Yeow Yeoh

[permalink] [raw]
Subject: [PATCH 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 setting 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]>
---
net/mac80211/mesh.c | 7 +++++--
net/mac80211/mesh_hwmp.c | 38 ++++++++++++++++++++++++++++++++++----
2 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 7cf1950..5e19e0d 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -541,11 +541,14 @@ 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);
+ interval = (ifmsh->mshcfg.dot11MeshHWMPRootMode == 4) ?
+ ifmsh->mshcfg.dot11MeshHWMPRannInterval :
+ 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..b1e4399 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -33,9 +33,11 @@
/* Reply and forward */
#define MP_F_RF 0x2
/* Unknown Sequence Number */
-#define MP_F_USN 0x01
+#define MP_F_USN 0x04
/* Reason code Present */
#define MP_F_RCODE 0x02
+/* Proactive PREQ with PREP */
+#define PREQ_F_PREP 0x04

static void mesh_queue_preq(struct mesh_path *, u8);

@@ -106,6 +108,14 @@ enum mpath_frame_type {
MPATH_RANN
};

+enum mesh_hwmp_rootmode {
+ noRoot = 0,
+ notavailable,
+ proactivePREQnoPREP,
+ proactivePREQwithPREP,
+ rann
+};
+
static const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
@@ -1157,13 +1167,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 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 proactivePREQwithPREP:
+ flags |= PREQ_F_PREP;
+ case proactivePREQnoPREP:
+ interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout;
+ target_flags |= MP_F_DO | MP_F_USN;
+ 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