mac80211: mesh: advertise gates in mesh formation
Subsystems (2)
PATCH 1/3 mac80211: mesh: advertise gates in mesh formation
The Connected to Mesh Gate subfield (802.11-2016 9.4.2.98.7) in the Mesh Formation Info field is currently unset. This field may be useful in determining which MBSSes to join or which mesh STAs to peer with.
If this mesh STA is a gate, by having turned on mesh gate announcements, or if we have a path to one (e.g. by having received RANNs) then set this bit to 1.
--- net/mac80211/mesh.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/mac80211/mesh.c +3 -1
@@ -254,6 +254,8 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;u8 *pos, neighbors;u8 meshconf_len =sizeof (struct ieee80211_meshconf_ie ); +bool is_connected_to_gate = ifmsh->num_gates >0 || + ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol;if (skb_tailroom (skb) <2 + meshconf_len)return -ENOMEM ;
@@ -278,7 +280,7 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,/* Mesh Formation Info - number of neighbors */ neighbors =atomic_read (&ifmsh->estab_plinks); neighbors =min_t (int, neighbors,IEEE80211_MAX_MESH_PEERINGS ); - *pos++ = neighbors <<1 ; + *pos++ = (neighbors <<1 ) | is_connected_to_gate;/* Mesh capability */ *pos =0x00 ; *pos |= ifmsh->mshcfg.dot11MeshForwarding ?
Signature · 1 line
2.11.0
PATCH 2/3 {nl,mac}80211: report gate connectivity in station info
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.
--- include/linux/ieee80211.h | 2 ++ include/net/cfg80211.h | 3 +++ include/uapi/linux/nl80211.h | 3 +++ net/mac80211/mesh_plink.c | 3 +++ net/mac80211/sta_info.c | 4 +++- net/mac80211/sta_info.h | 2 ++ net/wireless/nl80211.c | 1 + 7 files changed, 17 insertions(+), 1 deletion(-)
include/linux/ieee80211.h +2 -0
@@ -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 *
include/net/cfg80211.h +3 -0
@@ -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;
include/uapi/linux/nl80211.h +3 -0
@@ -3074,6 +3074,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 */
@@ -3116,6 +3118,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,
net/mac80211/mesh_plink.c +3 -0
@@ -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 &&
net/mac80211/sta_info.c +3 -1
@@ -2267,7 +2267,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;
@@ -2279,6 +2280,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 }
net/mac80211/sta_info.h +2 -0
@@ -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;
net/wireless/nl80211.c +1 -0
@@ -4731,6 +4731,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 );
Signature · 1 line
2.11.0
PATCH 3/3 {nl,mac}80211: add dot11MeshConnectedToMeshGate to meshconf
In reply to Bob CopelandWhen userspace is controlling mesh routing, it may have better knowledge about whether a mesh STA is connected to a mesh gate than the kernel mpath table. Add dot11MeshConnectedToMeshGate to the mesh config so that such applications can explicitly signal that a mesh STA is connected to a gate, which will then be advertised in the beacon.
--- include/net/cfg80211.h | 5 +++++ include/uapi/linux/nl80211.h | 6 ++++++ net/mac80211/cfg.c | 3 +++ net/mac80211/debugfs_netdev.c | 3 +++ net/mac80211/mesh.c | 3 ++- net/wireless/nl80211.c | 8 +++++++- 6 files changed, 26 insertions(+), 2 deletions(-)
include/net/cfg80211.h +5 -0
@@ -1562,6 +1562,10 @@ struct bss_parameters {* @plink_timeout: If no tx activity is seen from a STA we've established * peering with for longer than this time (in seconds), then remove it * from the STA's list of peers. Default is 30 minutes. +* @dot11MeshConnectedToMeshGate: if set to true, advertise that this STA is +* connected to a mesh gate in mesh formation info. If false, the +* value in mesh formation is determined by the presence of root paths +* in the mesh path table */ struct mesh_config {u16 dot11MeshRetryTimeout;
@@ -1581,6 +1585,7 @@ struct mesh_config {u16 dot11MeshHWMPperrMinInterval;u16 dot11MeshHWMPnetDiameterTraversalTime;u8 dot11MeshHWMPRootMode; +bool dot11MeshConnectedToMeshGate;u16 dot11MeshHWMPRannInterval;bool dot11MeshGateAnnouncementProtocol;bool dot11MeshForwarding;
include/uapi/linux/nl80211.h +6 -0
@@ -3898,6 +3898,11 @@ enum nl80211_mesh_power_mode {* remove it from the STA's list of peers. You may set this to 0 to disable * the removal of the STA. Default is 30 minutes. * +* @NL80211_MESHCONF_CONNECTED_TO_GATE: If set to true then this mesh STA +* will advertise that it is connected to a gate in the mesh formation +* field. If left unset then the mesh formation field will only +* advertise such if there is an active root mesh path. +* * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use */ enum nl80211_meshconf_params {
@@ -3930,6 +3935,7 @@ enum nl80211_meshconf_params {NL80211_MESHCONF_POWER_MODE ,NL80211_MESHCONF_AWAKE_WINDOW ,NL80211_MESHCONF_PLINK_TIMEOUT , +NL80211_MESHCONF_CONNECTED_TO_GATE ,/* keep last */ __NL80211_MESHCONF_ATTR_AFTER_LAST,
net/mac80211/cfg.c +3 -0
@@ -2028,6 +2028,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, nconf->dot11MeshAwakeWindowDuration;if (_chg_mesh_attr (NL80211_MESHCONF_PLINK_TIMEOUT , mask)) conf->plink_timeout = nconf->plink_timeout; +if (_chg_mesh_attr (NL80211_MESHCONF_CONNECTED_TO_GATE , mask)) + conf->dot11MeshConnectedToMeshGate = + nconf->dot11MeshConnectedToMeshGate;ieee80211_mbss_info_change_notify (sdata,BSS_CHANGED_BEACON );return 0 ; }
net/mac80211/debugfs_netdev.c +3 -0
@@ -641,6 +641,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,IEEE80211_IF_FILE (power_mode, u.mesh.mshcfg.power_mode,DEC );IEEE80211_IF_FILE (dot11MeshAwakeWindowDuration, u.mesh.mshcfg.dot11MeshAwakeWindowDuration,DEC ); +IEEE80211_IF_FILE (dot11MeshConnectedToMeshGate, + u.mesh.mshcfg.dot11MeshConnectedToMeshGate,DEC );#endif #define DEBUGFS_ADD_MODE (name, mode) \
@@ -762,6 +764,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)MESHPARAMS_ADD (dot11MeshHWMPconfirmationInterval);MESHPARAMS_ADD (power_mode);MESHPARAMS_ADD (dot11MeshAwakeWindowDuration); +MESHPARAMS_ADD (dot11MeshConnectedToMeshGate);#undef MESHPARAMS_ADD }#endif
net/mac80211/mesh.c +2 -1
@@ -255,7 +255,8 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,u8 *pos, neighbors;u8 meshconf_len =sizeof (struct ieee80211_meshconf_ie );bool is_connected_to_gate = ifmsh->num_gates >0 || - ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol; + ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol || + ifmsh->mshcfg.dot11MeshConnectedToMeshGate;if (skb_tailroom (skb) <2 + meshconf_len)return -ENOMEM ;
net/wireless/nl80211.c +7 -1
@@ -6123,7 +6123,9 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,nla_put_u16 (msg,NL80211_MESHCONF_AWAKE_WINDOW , cur_params.dot11MeshAwakeWindowDuration) ||nla_put_u32 (msg,NL80211_MESHCONF_PLINK_TIMEOUT , - cur_params.plink_timeout)) + cur_params.plink_timeout) || +nla_put_u8 (msg,NL80211_MESHCONF_CONNECTED_TO_GATE , + cur_params.dot11MeshConnectedToMeshGate)) goto nla_put_failure;nla_nest_end (msg, pinfoattr);genlmsg_end (msg, hdr);
@@ -6180,6 +6182,7 @@ nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = { NL80211_MESH_POWER_MAX), [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 }, [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 }, + [NL80211_MESHCONF_CONNECTED_TO_GATE] = { .type = NLA_U8 }, }; static const struct nla_policy
@@ -6291,6 +6294,9 @@ do { \FILL_IN_MESH_PARAM_IF_SET (tb, cfg, rssi_threshold, mask,NL80211_MESHCONF_RSSI_THRESHOLD , nla_get_s32); +FILL_IN_MESH_PARAM_IF_SET (tb, cfg, dot11MeshConnectedToMeshGate, mask, +NL80211_MESHCONF_CONNECTED_TO_GATE , + nla_get_u8);/* * Check HT operation mode based on * IEEE 802.11-2016 9.4.2.57 HT Operation element.
Signature · 1 line
2.11.0
PATCH v2 3/3 {nl,mac}80211: add dot11MeshConnectedToMeshGate to meshconf
When userspace is controlling mesh routing, it may have better knowledge about whether a mesh STA is connected to a mesh gate than the kernel mpath table. Add dot11MeshConnectedToMeshGate to the mesh config so that such applications can explicitly signal that a mesh STA is connected to a gate, which will then be advertised in the beacon.
---
v2: add policy range and type comment
include/net/cfg80211.h | 5 +++++ include/uapi/linux/nl80211.h | 8 +++++++- net/mac80211/cfg.c | 3 +++ net/mac80211/debugfs_netdev.c | 3 +++ net/mac80211/mesh.c | 3 ++- net/wireless/nl80211.c | 8 +++++++- 6 files changed, 27 insertions(+), 3 deletions(-)
include/net/cfg80211.h +5 -0
@@ -1562,6 +1562,10 @@ struct bss_parameters {* @plink_timeout: If no tx activity is seen from a STA we've established * peering with for longer than this time (in seconds), then remove it * from the STA's list of peers. Default is 30 minutes. +* @dot11MeshConnectedToMeshGate: if set to true, advertise that this STA is +* connected to a mesh gate in mesh formation info. If false, the +* value in mesh formation is determined by the presence of root paths +* in the mesh path table */ struct mesh_config {u16 dot11MeshRetryTimeout;
@@ -1581,6 +1585,7 @@ struct mesh_config {u16 dot11MeshHWMPperrMinInterval;u16 dot11MeshHWMPnetDiameterTraversalTime;u8 dot11MeshHWMPRootMode; +bool dot11MeshConnectedToMeshGate;u16 dot11MeshHWMPRannInterval;bool dot11MeshGateAnnouncementProtocol;bool dot11MeshForwarding;
include/uapi/linux/nl80211.h +7 -1
@@ -3075,7 +3075,7 @@ enum nl80211_sta_bss_param {* 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 +* mesh gate (u8, 0 or 1) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */
@@ -3898,6 +3898,11 @@ enum nl80211_mesh_power_mode {* remove it from the STA's list of peers. You may set this to 0 to disable * the removal of the STA. Default is 30 minutes. * +* @NL80211_MESHCONF_CONNECTED_TO_GATE: If set to true then this mesh STA +* will advertise that it is connected to a gate in the mesh formation +* field. If left unset then the mesh formation field will only +* advertise such if there is an active root mesh path. +* * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use */ enum nl80211_meshconf_params {
@@ -3930,6 +3935,7 @@ enum nl80211_meshconf_params {NL80211_MESHCONF_POWER_MODE ,NL80211_MESHCONF_AWAKE_WINDOW ,NL80211_MESHCONF_PLINK_TIMEOUT , +NL80211_MESHCONF_CONNECTED_TO_GATE ,/* keep last */ __NL80211_MESHCONF_ATTR_AFTER_LAST,
net/mac80211/cfg.c +3 -0
@@ -2028,6 +2028,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, nconf->dot11MeshAwakeWindowDuration;if (_chg_mesh_attr (NL80211_MESHCONF_PLINK_TIMEOUT , mask)) conf->plink_timeout = nconf->plink_timeout; +if (_chg_mesh_attr (NL80211_MESHCONF_CONNECTED_TO_GATE , mask)) + conf->dot11MeshConnectedToMeshGate = + nconf->dot11MeshConnectedToMeshGate;ieee80211_mbss_info_change_notify (sdata,BSS_CHANGED_BEACON );return 0 ; }
net/mac80211/debugfs_netdev.c +3 -0
@@ -641,6 +641,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,IEEE80211_IF_FILE (power_mode, u.mesh.mshcfg.power_mode,DEC );IEEE80211_IF_FILE (dot11MeshAwakeWindowDuration, u.mesh.mshcfg.dot11MeshAwakeWindowDuration,DEC ); +IEEE80211_IF_FILE (dot11MeshConnectedToMeshGate, + u.mesh.mshcfg.dot11MeshConnectedToMeshGate,DEC );#endif #define DEBUGFS_ADD_MODE (name, mode) \
@@ -762,6 +764,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)MESHPARAMS_ADD (dot11MeshHWMPconfirmationInterval);MESHPARAMS_ADD (power_mode);MESHPARAMS_ADD (dot11MeshAwakeWindowDuration); +MESHPARAMS_ADD (dot11MeshConnectedToMeshGate);#undef MESHPARAMS_ADD }#endif
net/mac80211/mesh.c +2 -1
@@ -255,7 +255,8 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,u8 *pos, neighbors;u8 meshconf_len =sizeof (struct ieee80211_meshconf_ie );bool is_connected_to_gate = ifmsh->num_gates >0 || - ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol; + ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol || + ifmsh->mshcfg.dot11MeshConnectedToMeshGate;if (skb_tailroom (skb) <2 + meshconf_len)return -ENOMEM ;
net/wireless/nl80211.c +7 -1
@@ -6123,7 +6123,9 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,nla_put_u16 (msg,NL80211_MESHCONF_AWAKE_WINDOW , cur_params.dot11MeshAwakeWindowDuration) ||nla_put_u32 (msg,NL80211_MESHCONF_PLINK_TIMEOUT , - cur_params.plink_timeout)) + cur_params.plink_timeout) || +nla_put_u8 (msg,NL80211_MESHCONF_CONNECTED_TO_GATE , + cur_params.dot11MeshConnectedToMeshGate)) goto nla_put_failure;nla_nest_end (msg, pinfoattr);genlmsg_end (msg, hdr);
@@ -6180,6 +6182,7 @@ nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = { NL80211_MESH_POWER_MAX), [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 }, [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 }, + [NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1), }; static const struct nla_policy
@@ -6291,6 +6294,9 @@ do { \FILL_IN_MESH_PARAM_IF_SET (tb, cfg, rssi_threshold, mask,NL80211_MESHCONF_RSSI_THRESHOLD , nla_get_s32); +FILL_IN_MESH_PARAM_IF_SET (tb, cfg, dot11MeshConnectedToMeshGate, mask, +NL80211_MESHCONF_CONNECTED_TO_GATE , + nla_get_u8);/* * Check HT operation mode based on * IEEE 802.11-2016 9.4.2.57 HT Operation element.
Signature · 1 line
2.11.0