diff options
-rw-r--r-- | include/linux/nl80211.h | 5 | ||||
-rw-r--r-- | include/net/cfg80211.h | 1 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 8 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 2 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 16 | ||||
-rw-r--r-- | net/wireless/mesh.c | 3 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 5 |
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, | |||
443 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, | 443 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, |
444 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); | 444 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); |
445 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); | 445 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); |
446 | IEEE80211_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 | |||
34 | enum plink_event { | 39 | enum 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 | ||
61 | const struct mesh_setup default_mesh_setup = { | 64 | const 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 | ||
3327 | static const struct nla_policy | 3330 | static 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 | ||