summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Copeland <me@bobcopeland.com>2018-10-26 10:03:50 -0400
committerJohannes Berg <johannes.berg@intel.com>2018-11-09 05:41:20 -0500
commitecbc12ad6b682680ae26a429225d7c295f7f0e77 (patch)
treecce1fb4e7885a968009126aba631b010d4f14e0e
parent01d66fbd5b18ac9f01a6a2ae1278189d19208ad5 (diff)
{nl,mac}80211: add rssi to mesh candidates
When peering is in userspace, some implementations may want to control which peers are accepted based on RSSI in addition to the information elements being sent today. Add signal level so that info is available to clients. Signed-off-by: Bob Copeland <bobcopeland@fb.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h3
-rw-r--r--net/mac80211/mesh.c3
-rw-r--r--net/mac80211/mesh.h3
-rw-r--r--net/mac80211/mesh_plink.c32
-rw-r--r--net/wireless/nl80211.c7
5 files changed, 33 insertions, 15 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 16d595b93ba3..ede7fcd68348 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5574,7 +5574,8 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
5574 * cfg80211 then sends a notification to userspace. 5574 * cfg80211 then sends a notification to userspace.
5575 */ 5575 */
5576void cfg80211_notify_new_peer_candidate(struct net_device *dev, 5576void cfg80211_notify_new_peer_candidate(struct net_device *dev,
5577 const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp); 5577 const u8 *macaddr, const u8 *ie, u8 ie_len,
5578 int sig_dbm, gfp_t gfp);
5578 5579
5579/** 5580/**
5580 * DOC: RFkill integration 5581 * DOC: RFkill integration
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 4869280a6413..c90452aa0c42 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1194,7 +1194,8 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
1194 if (!sdata->u.mesh.user_mpm || 1194 if (!sdata->u.mesh.user_mpm ||
1195 sdata->u.mesh.mshcfg.rssi_threshold == 0 || 1195 sdata->u.mesh.mshcfg.rssi_threshold == 0 ||
1196 sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal) 1196 sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal)
1197 mesh_neighbour_update(sdata, mgmt->sa, &elems); 1197 mesh_neighbour_update(sdata, mgmt->sa, &elems,
1198 rx_status);
1198 } 1199 }
1199 1200
1200 if (ifmsh->sync_ops) 1201 if (ifmsh->sync_ops)
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 21526630bf65..cad6592c52a1 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -273,7 +273,8 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
273 273
274/* Mesh plinks */ 274/* Mesh plinks */
275void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, 275void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
276 u8 *hw_addr, struct ieee802_11_elems *ie); 276 u8 *hw_addr, struct ieee802_11_elems *ie,
277 struct ieee80211_rx_status *rx_status);
277bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 278bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
278u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 279u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
279void mesh_plink_timer(struct timer_list *t); 280void mesh_plink_timer(struct timer_list *t);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 5f45a2b273df..33055c8ed37e 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -513,7 +513,8 @@ __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr)
513 513
514static struct sta_info * 514static struct sta_info *
515mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr, 515mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
516 struct ieee802_11_elems *elems) 516 struct ieee802_11_elems *elems,
517 struct ieee80211_rx_status *rx_status)
517{ 518{
518 struct sta_info *sta = NULL; 519 struct sta_info *sta = NULL;
519 520
@@ -521,11 +522,17 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
521 if (sdata->u.mesh.user_mpm || 522 if (sdata->u.mesh.user_mpm ||
522 sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) { 523 sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) {
523 if (mesh_peer_accepts_plinks(elems) && 524 if (mesh_peer_accepts_plinks(elems) &&
524 mesh_plink_availables(sdata)) 525 mesh_plink_availables(sdata)) {
526 int sig = 0;
527
528 if (ieee80211_hw_check(&sdata->local->hw, SIGNAL_DBM))
529 sig = rx_status->signal;
530
525 cfg80211_notify_new_peer_candidate(sdata->dev, addr, 531 cfg80211_notify_new_peer_candidate(sdata->dev, addr,
526 elems->ie_start, 532 elems->ie_start,
527 elems->total_len, 533 elems->total_len,
528 GFP_KERNEL); 534 sig, GFP_KERNEL);
535 }
529 } else 536 } else
530 sta = __mesh_sta_info_alloc(sdata, addr); 537 sta = __mesh_sta_info_alloc(sdata, addr);
531 538
@@ -538,13 +545,15 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
538 * @sdata: local meshif 545 * @sdata: local meshif
539 * @addr: peer's address 546 * @addr: peer's address
540 * @elems: IEs from beacon or mesh peering frame. 547 * @elems: IEs from beacon or mesh peering frame.
548 * @rx_status: rx status for the frame for signal reporting
541 * 549 *
542 * Return existing or newly allocated sta_info under RCU read lock. 550 * Return existing or newly allocated sta_info under RCU read lock.
543 * (re)initialize with given IEs. 551 * (re)initialize with given IEs.
544 */ 552 */
545static struct sta_info * 553static struct sta_info *
546mesh_sta_info_get(struct ieee80211_sub_if_data *sdata, 554mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
547 u8 *addr, struct ieee802_11_elems *elems) __acquires(RCU) 555 u8 *addr, struct ieee802_11_elems *elems,
556 struct ieee80211_rx_status *rx_status) __acquires(RCU)
548{ 557{
549 struct sta_info *sta = NULL; 558 struct sta_info *sta = NULL;
550 559
@@ -555,7 +564,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
555 } else { 564 } else {
556 rcu_read_unlock(); 565 rcu_read_unlock();
557 /* can't run atomic */ 566 /* can't run atomic */
558 sta = mesh_sta_info_alloc(sdata, addr, elems); 567 sta = mesh_sta_info_alloc(sdata, addr, elems, rx_status);
559 if (!sta) { 568 if (!sta) {
560 rcu_read_lock(); 569 rcu_read_lock();
561 return NULL; 570 return NULL;
@@ -576,17 +585,19 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
576 * @sdata: local meshif 585 * @sdata: local meshif
577 * @addr: peer's address 586 * @addr: peer's address
578 * @elems: IEs from beacon or mesh peering frame 587 * @elems: IEs from beacon or mesh peering frame
588 * @rx_status: rx status for the frame for signal reporting
579 * 589 *
580 * Initiates peering if appropriate. 590 * Initiates peering if appropriate.
581 */ 591 */
582void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, 592void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
583 u8 *hw_addr, 593 u8 *hw_addr,
584 struct ieee802_11_elems *elems) 594 struct ieee802_11_elems *elems,
595 struct ieee80211_rx_status *rx_status)
585{ 596{
586 struct sta_info *sta; 597 struct sta_info *sta;
587 u32 changed = 0; 598 u32 changed = 0;
588 599
589 sta = mesh_sta_info_get(sdata, hw_addr, elems); 600 sta = mesh_sta_info_get(sdata, hw_addr, elems, rx_status);
590 if (!sta) 601 if (!sta)
591 goto out; 602 goto out;
592 603
@@ -1072,7 +1083,8 @@ out:
1072static void 1083static void
1073mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, 1084mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
1074 struct ieee80211_mgmt *mgmt, 1085 struct ieee80211_mgmt *mgmt,
1075 struct ieee802_11_elems *elems) 1086 struct ieee802_11_elems *elems,
1087 struct ieee80211_rx_status *rx_status)
1076{ 1088{
1077 1089
1078 struct sta_info *sta; 1090 struct sta_info *sta;
@@ -1137,7 +1149,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
1137 if (event == OPN_ACPT) { 1149 if (event == OPN_ACPT) {
1138 rcu_read_unlock(); 1150 rcu_read_unlock();
1139 /* allocate sta entry if necessary and update info */ 1151 /* allocate sta entry if necessary and update info */
1140 sta = mesh_sta_info_get(sdata, mgmt->sa, elems); 1152 sta = mesh_sta_info_get(sdata, mgmt->sa, elems, rx_status);
1141 if (!sta) { 1153 if (!sta) {
1142 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n"); 1154 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
1143 goto unlock_rcu; 1155 goto unlock_rcu;
@@ -1203,5 +1215,5 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
1203 return; 1215 return;
1204 } 1216 }
1205 ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems); 1217 ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems);
1206 mesh_process_plink_frame(sdata, mgmt, &elems); 1218 mesh_process_plink_frame(sdata, mgmt, &elems, rx_status);
1207} 1219}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d5f0ffd076b2..e20329b34840 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14735,7 +14735,8 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
14735} 14735}
14736 14736
14737void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr, 14737void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
14738 const u8* ie, u8 ie_len, gfp_t gfp) 14738 const u8 *ie, u8 ie_len,
14739 int sig_dbm, gfp_t gfp)
14739{ 14740{
14740 struct wireless_dev *wdev = dev->ieee80211_ptr; 14741 struct wireless_dev *wdev = dev->ieee80211_ptr;
14741 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 14742 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
@@ -14761,7 +14762,9 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
14761 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || 14762 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14762 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || 14763 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
14763 (ie_len && ie && 14764 (ie_len && ie &&
14764 nla_put(msg, NL80211_ATTR_IE, ie_len , ie))) 14765 nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) ||
14766 (sig_dbm &&
14767 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)))
14765 goto nla_put_failure; 14768 goto nla_put_failure;
14766 14769
14767 genlmsg_end(msg, hdr); 14770 genlmsg_end(msg, hdr);