{nl,mac}80211: report gate connectivity in station info
authorBob Copeland <me@bobcopeland.com>
Thu, 25 Oct 2018 19:48:53 +0000 (15:48 -0400)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 9 Nov 2018 10:38:29 +0000 (11:38 +0100)
Capture the current state of gate connectivity from the mesh
formation field in mesh config whenever we receive a beacon,
and report that via GET_STATION.  This allows applications
doing mesh peering in userspace to make peering decisions
based on peers' current upstream connectivity.

Signed-off-by: Bob Copeland <bobcopeland@fb.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/linux/ieee80211.h
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/mac80211/mesh_plink.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/wireless/nl80211.c

index 0ef67f837ae12de08fd8a39532d794463d579f82..407d6fd66fa95da4e629b17928df4a657b545c2e 100644 (file)
@@ -812,6 +812,8 @@ enum mesh_config_capab_flags {
        IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL       = 0x40,
 };
 
+#define IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE 0x1
+
 /**
  * mesh channel switch parameters element's flag indicator
  *
index c21c5c70a2fde1a843b1b5b9488d827c2943b403..24d2db8e082ddaf928627d96f9a8e363adf8c9ed 100644 (file)
@@ -1296,6 +1296,7 @@ struct cfg80211_tid_stats {
  * @rx_beacon: number of beacons received from this peer
  * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received
  *     from this peer
+ * @connected_to_gate: true if mesh STA has a path to mesh gate
  * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer
  * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last
  *     (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs.
@@ -1350,6 +1351,8 @@ struct station_info {
        u64 rx_beacon;
        u64 rx_duration;
        u8 rx_beacon_signal_avg;
+       u8 connected_to_gate;
+
        struct cfg80211_tid_stats *pertid;
        s8 ack_signal;
        s8 avg_ack_signal;
index e45b8892578363006d9f49378d2b13e6c75107a8..ff6005edf32f7873f20044725c9a1a9db2cc66f4 100644 (file)
@@ -3116,6 +3116,8 @@ enum nl80211_sta_bss_param {
  *     with an FCS error (u32, from this station). This count may not include
  *     some packets with an FCS error due to TA corruption. Hence this counter
  *     might not be fully accurate.
+ * @NL80211_STA_INFO_CONNECTED_TO_GATE: set to true if STA has a path to a
+ *     mesh gate
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
@@ -3158,6 +3160,7 @@ enum nl80211_sta_info {
        NL80211_STA_INFO_ACK_SIGNAL_AVG,
        NL80211_STA_INFO_RX_MPDUS,
        NL80211_STA_INFO_FCS_ERROR_COUNT,
+       NL80211_STA_INFO_CONNECTED_TO_GATE,
 
        /* keep last */
        __NL80211_STA_INFO_AFTER_LAST,
index 5b5b0f95ffd13ecef6feeab6a0f2d64e36ba6561..5f45a2b273df52c7d927f8d4fd69fe64bd546676 100644 (file)
@@ -590,6 +590,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
        if (!sta)
                goto out;
 
+       sta->mesh->connected_to_gate = elems->mesh_config->meshconf_form &
+               IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE;
+
        if (mesh_peer_accepts_plinks(elems) &&
            sta->mesh->plink_state == NL80211_PLINK_LISTEN &&
            sdata->u.mesh.accepting_plinks &&
index 11b7ae691db01d98d5af381d0247cd597d894744..c4a8f115ed332052ee127e223a5e5781e334f59b 100644 (file)
@@ -2264,7 +2264,8 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
                                 BIT_ULL(NL80211_STA_INFO_PLINK_STATE) |
                                 BIT_ULL(NL80211_STA_INFO_LOCAL_PM) |
                                 BIT_ULL(NL80211_STA_INFO_PEER_PM) |
-                                BIT_ULL(NL80211_STA_INFO_NONPEER_PM);
+                                BIT_ULL(NL80211_STA_INFO_NONPEER_PM) |
+                                BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_GATE);
 
                sinfo->llid = sta->mesh->llid;
                sinfo->plid = sta->mesh->plid;
@@ -2276,6 +2277,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
                sinfo->local_pm = sta->mesh->local_pm;
                sinfo->peer_pm = sta->mesh->peer_pm;
                sinfo->nonpeer_pm = sta->mesh->nonpeer_pm;
+               sinfo->connected_to_gate = sta->mesh->connected_to_gate;
 #endif
        }
 
index 9a04327d71d1de1129a7589195c574e8b62fa74c..8eb29041be54b1af438c50532cd9861740061263 100644 (file)
@@ -364,6 +364,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8)
  * @nonpeer_pm: STA power save mode towards non-peer neighbors
  * @processed_beacon: set to true after peer rates and capabilities are
  *     processed
+ * @connected_to_gate: true if mesh STA has a path to a mesh gate
  * @fail_avg: moving percentage of failed MSDUs
  */
 struct mesh_sta {
@@ -381,6 +382,7 @@ struct mesh_sta {
        u8 plink_retries;
 
        bool processed_beacon;
+       bool connected_to_gate;
 
        enum nl80211_plink_state plink_state;
        u32 plink_timeout;
index 5e7178954d615f0128b0270e1797902d525bbf27..f231059242ccc881cdafbaa12af06e09a097273e 100644 (file)
@@ -4883,6 +4883,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
        PUT_SINFO(LOCAL_PM, local_pm, u32);
        PUT_SINFO(PEER_PM, peer_pm, u32);
        PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
+       PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
 
        if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
                bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);