aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/nl80211.h5
-rw-r--r--include/net/cfg80211.h1
-rw-r--r--net/mac80211/cfg.c8
-rw-r--r--net/mac80211/debugfs_netdev.c2
-rw-r--r--net/mac80211/mesh_plink.c16
-rw-r--r--net/wireless/mesh.c3
-rw-r--r--net/wireless/nl80211.c5
7 files changed, 39 insertions, 1 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index be35a68746a7..38fda5ee57f5 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -2112,6 +2112,10 @@ enum nl80211_mntr_flags {
2112 * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding 2112 * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding
2113 * or forwarding entity (default is TRUE - forwarding entity) 2113 * or forwarding entity (default is TRUE - forwarding entity)
2114 * 2114 *
2115 * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the
2116 * threshold for average signal strength of candidate station to establish
2117 * a peer link.
2118 *
2115 * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute 2119 * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
2116 * 2120 *
2117 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use 2121 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -2137,6 +2141,7 @@ enum nl80211_meshconf_params {
2137 NL80211_MESHCONF_GATE_ANNOUNCEMENTS, 2141 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
2138 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, 2142 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
2139 NL80211_MESHCONF_FORWARDING, 2143 NL80211_MESHCONF_FORWARDING,
2144 NL80211_MESHCONF_RSSI_THRESHOLD,
2140 2145
2141 /* keep last */ 2146 /* keep last */
2142 __NL80211_MESHCONF_ATTR_AFTER_LAST, 2147 __NL80211_MESHCONF_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0178c7489373..b4e015c90885 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -809,6 +809,7 @@ struct mesh_config {
809 * Still keeping the same nomenclature to be in sync with the spec. */ 809 * Still keeping the same nomenclature to be in sync with the spec. */
810 bool dot11MeshGateAnnouncementProtocol; 810 bool dot11MeshGateAnnouncementProtocol;
811 bool dot11MeshForwarding; 811 bool dot11MeshForwarding;
812 s32 rssi_threshold;
812}; 813};
813 814
814/** 815/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6a77d4c910f9..ab31cc56a2fb 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1314,6 +1314,14 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1314 } 1314 }
1315 if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) 1315 if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
1316 conf->dot11MeshForwarding = nconf->dot11MeshForwarding; 1316 conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
1317 if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
1318 /* our RSSI threshold implementation is supported only for
1319 * devices that report signal in dBm.
1320 */
1321 if (!(sdata->local->hw.flags & IEEE80211_HW_SIGNAL_DBM))
1322 return -ENOTSUPP;
1323 conf->rssi_threshold = nconf->rssi_threshold;
1324 }
1317 return 0; 1325 return 0;
1318} 1326}
1319 1327
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 510ed1dab3c7..9f484d8905fd 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -443,6 +443,7 @@ IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
443IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, 443IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
444 u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); 444 u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
445IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); 445IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
446IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
446#endif 447#endif
447 448
448 449
@@ -581,6 +582,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
581 MESHPARAMS_ADD(dot11MeshHWMPRootMode); 582 MESHPARAMS_ADD(dot11MeshHWMPRootMode);
582 MESHPARAMS_ADD(dot11MeshHWMPRannInterval); 583 MESHPARAMS_ADD(dot11MeshHWMPRannInterval);
583 MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); 584 MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
585 MESHPARAMS_ADD(rssi_threshold);
584#undef MESHPARAMS_ADD 586#undef MESHPARAMS_ADD
585} 587}
586#endif 588#endif
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 8806e5ef8ffe..80ce52772538 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -31,6 +31,11 @@
31#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) 31#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
32#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) 32#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
33 33
34#define sta_meets_rssi_threshold(sta, sdata) \
35 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
36 (s8) -ewma_read(&sta->avg_signal) > \
37 sdata->u.mesh.mshcfg.rssi_threshold)
38
34enum plink_event { 39enum plink_event {
35 PLINK_UNDEFINED, 40 PLINK_UNDEFINED,
36 OPN_ACPT, 41 OPN_ACPT,
@@ -301,7 +306,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
301 if (mesh_peer_accepts_plinks(elems) && 306 if (mesh_peer_accepts_plinks(elems) &&
302 sta->plink_state == NL80211_PLINK_LISTEN && 307 sta->plink_state == NL80211_PLINK_LISTEN &&
303 sdata->u.mesh.accepting_plinks && 308 sdata->u.mesh.accepting_plinks &&
304 sdata->u.mesh.mshcfg.auto_open_plinks) 309 sdata->u.mesh.mshcfg.auto_open_plinks &&
310 sta_meets_rssi_threshold(sta, sdata))
305 mesh_plink_open(sta); 311 mesh_plink_open(sta);
306 312
307 rcu_read_unlock(); 313 rcu_read_unlock();
@@ -531,6 +537,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
531 return; 537 return;
532 } 538 }
533 539
540 if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
541 !sta_meets_rssi_threshold(sta, sdata)) {
542 mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n",
543 sta->sta.addr);
544 rcu_read_unlock();
545 return;
546 }
547
534 if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { 548 if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
535 mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); 549 mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
536 rcu_read_unlock(); 550 rcu_read_unlock();
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 9d3e3b6bfcf4..ba21ab22187b 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -23,6 +23,8 @@
23#define MESH_PERR_MIN_INT 100 23#define MESH_PERR_MIN_INT 100
24#define MESH_DIAM_TRAVERSAL_TIME 50 24#define MESH_DIAM_TRAVERSAL_TIME 50
25 25
26#define MESH_RSSI_THRESHOLD 0
27
26/* 28/*
27 * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds 29 * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds
28 * before timing out. This way it will remain ACTIVE and no data frames 30 * before timing out. This way it will remain ACTIVE and no data frames
@@ -56,6 +58,7 @@ const struct mesh_config default_mesh_config = {
56 .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL, 58 .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
57 .dot11MeshGateAnnouncementProtocol = false, 59 .dot11MeshGateAnnouncementProtocol = false,
58 .dot11MeshForwarding = true, 60 .dot11MeshForwarding = true,
61 .rssi_threshold = MESH_RSSI_THRESHOLD,
59}; 62};
60 63
61const struct mesh_setup default_mesh_setup = { 64const struct mesh_setup default_mesh_setup = {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1998c3682774..25a470abd21d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3290,6 +3290,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
3290 cur_params.dot11MeshGateAnnouncementProtocol); 3290 cur_params.dot11MeshGateAnnouncementProtocol);
3291 NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING, 3291 NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING,
3292 cur_params.dot11MeshForwarding); 3292 cur_params.dot11MeshForwarding);
3293 NLA_PUT_U32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
3294 cur_params.rssi_threshold);
3293 nla_nest_end(msg, pinfoattr); 3295 nla_nest_end(msg, pinfoattr);
3294 genlmsg_end(msg, hdr); 3296 genlmsg_end(msg, hdr);
3295 return genlmsg_reply(msg, info); 3297 return genlmsg_reply(msg, info);
@@ -3322,6 +3324,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3322 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, 3324 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
3323 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, 3325 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
3324 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, 3326 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
3327 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32},
3325}; 3328};
3326 3329
3327static const struct nla_policy 3330static const struct nla_policy
@@ -3413,6 +3416,8 @@ do {\
3413 nla_get_u8); 3416 nla_get_u8);
3414 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 3417 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
3415 mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); 3418 mask, NL80211_MESHCONF_FORWARDING, nla_get_u8);
3419 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
3420 mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32);
3416 if (mask_out) 3421 if (mask_out)
3417 *mask_out = mask; 3422 *mask_out = mask;
3418 3423