aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/mesh.c21
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_plink.c44
3 files changed, 33 insertions, 34 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index f2d0d213bcfb..f4a636ffe023 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -136,10 +136,13 @@ bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
136 * mesh_accept_plinks_update - update accepting_plink in local mesh beacons 136 * mesh_accept_plinks_update - update accepting_plink in local mesh beacons
137 * 137 *
138 * @sdata: mesh interface in which mesh beacons are going to be updated 138 * @sdata: mesh interface in which mesh beacons are going to be updated
139 *
140 * Returns: beacon changed flag if the beacon content changed.
139 */ 141 */
140void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) 142u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
141{ 143{
142 bool free_plinks; 144 bool free_plinks;
145 u32 changed = 0;
143 146
144 /* In case mesh_plink_free_count > 0 and mesh_plinktbl_capacity == 0, 147 /* In case mesh_plink_free_count > 0 and mesh_plinktbl_capacity == 0,
145 * the mesh interface might be able to establish plinks with peers that 148 * the mesh interface might be able to establish plinks with peers that
@@ -149,8 +152,12 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
149 */ 152 */
150 free_plinks = mesh_plink_availables(sdata); 153 free_plinks = mesh_plink_availables(sdata);
151 154
152 if (free_plinks != sdata->u.mesh.accepting_plinks) 155 if (free_plinks != sdata->u.mesh.accepting_plinks) {
153 ieee80211_mesh_housekeeping_timer((unsigned long) sdata); 156 sdata->u.mesh.accepting_plinks = free_plinks;
157 changed = BSS_CHANGED_BEACON;
158 }
159
160 return changed;
154} 161}
155 162
156int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 163int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -262,7 +269,6 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
262 neighbors = (neighbors > 15) ? 15 : neighbors; 269 neighbors = (neighbors > 15) ? 15 : neighbors;
263 *pos++ = neighbors << 1; 270 *pos++ = neighbors << 1;
264 /* Mesh capability */ 271 /* Mesh capability */
265 ifmsh->accepting_plinks = mesh_plink_availables(sdata);
266 *pos = MESHCONF_CAPAB_FORWARDING; 272 *pos = MESHCONF_CAPAB_FORWARDING;
267 *pos |= ifmsh->accepting_plinks ? 273 *pos |= ifmsh->accepting_plinks ?
268 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 274 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
@@ -523,14 +529,13 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
523static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, 529static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
524 struct ieee80211_if_mesh *ifmsh) 530 struct ieee80211_if_mesh *ifmsh)
525{ 531{
526 bool free_plinks; 532 u32 changed;
527 533
528 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); 534 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
529 mesh_path_expire(sdata); 535 mesh_path_expire(sdata);
530 536
531 free_plinks = mesh_plink_availables(sdata); 537 changed = mesh_accept_plinks_update(sdata);
532 if (free_plinks != sdata->u.mesh.accepting_plinks) 538 ieee80211_bss_info_change_notify(sdata, changed);
533 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
534 539
535 mod_timer(&ifmsh->housekeeping_timer, 540 mod_timer(&ifmsh->housekeeping_timer,
536 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); 541 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index e4d911ffd5d1..25d0f17dec71 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -285,7 +285,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
285 u8 *hw_addr, 285 u8 *hw_addr,
286 struct ieee802_11_elems *ie); 286 struct ieee802_11_elems *ie);
287bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 287bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
288void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 288u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
289void mesh_plink_broken(struct sta_info *sta); 289void mesh_plink_broken(struct sta_info *sta);
290void mesh_plink_deactivate(struct sta_info *sta); 290void mesh_plink_deactivate(struct sta_info *sta);
291int mesh_plink_open(struct sta_info *sta); 291int mesh_plink_open(struct sta_info *sta);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 54ce1af491eb..9d7ad366ef09 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -48,17 +48,17 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
48 u8 *da, __le16 llid, __le16 plid, __le16 reason); 48 u8 *da, __le16 llid, __le16 plid, __le16 reason);
49 49
50static inline 50static inline
51void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 51u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
52{ 52{
53 atomic_inc(&sdata->u.mesh.mshstats.estab_plinks); 53 atomic_inc(&sdata->u.mesh.mshstats.estab_plinks);
54 mesh_accept_plinks_update(sdata); 54 return mesh_accept_plinks_update(sdata);
55} 55}
56 56
57static inline 57static inline
58void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) 58u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
59{ 59{
60 atomic_dec(&sdata->u.mesh.mshstats.estab_plinks); 60 atomic_dec(&sdata->u.mesh.mshstats.estab_plinks);
61 mesh_accept_plinks_update(sdata); 61 return mesh_accept_plinks_update(sdata);
62} 62}
63 63
64/** 64/**
@@ -171,22 +171,21 @@ out:
171 * @sta: mesh peer link to deactivate 171 * @sta: mesh peer link to deactivate
172 * 172 *
173 * All mesh paths with this peer as next hop will be flushed 173 * All mesh paths with this peer as next hop will be flushed
174 * Returns beacon changed flag if the beacon content changed.
174 * 175 *
175 * Locking: the caller must hold sta->lock 176 * Locking: the caller must hold sta->lock
176 */ 177 */
177static bool __mesh_plink_deactivate(struct sta_info *sta) 178static u32 __mesh_plink_deactivate(struct sta_info *sta)
178{ 179{
179 struct ieee80211_sub_if_data *sdata = sta->sdata; 180 struct ieee80211_sub_if_data *sdata = sta->sdata;
180 bool deactivated = false; 181 u32 changed = 0;
181 182
182 if (sta->plink_state == NL80211_PLINK_ESTAB) { 183 if (sta->plink_state == NL80211_PLINK_ESTAB)
183 mesh_plink_dec_estab_count(sdata); 184 changed = mesh_plink_dec_estab_count(sdata);
184 deactivated = true;
185 }
186 sta->plink_state = NL80211_PLINK_BLOCKED; 185 sta->plink_state = NL80211_PLINK_BLOCKED;
187 mesh_path_flush_by_nexthop(sta); 186 mesh_path_flush_by_nexthop(sta);
188 187
189 return deactivated; 188 return changed;
190} 189}
191 190
192/** 191/**
@@ -199,18 +198,17 @@ static bool __mesh_plink_deactivate(struct sta_info *sta)
199void mesh_plink_deactivate(struct sta_info *sta) 198void mesh_plink_deactivate(struct sta_info *sta)
200{ 199{
201 struct ieee80211_sub_if_data *sdata = sta->sdata; 200 struct ieee80211_sub_if_data *sdata = sta->sdata;
202 bool deactivated; 201 u32 changed;
203 202
204 spin_lock_bh(&sta->lock); 203 spin_lock_bh(&sta->lock);
205 deactivated = __mesh_plink_deactivate(sta); 204 changed = __mesh_plink_deactivate(sta);
206 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED); 205 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED);
207 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 206 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
208 sta->sta.addr, sta->llid, sta->plid, 207 sta->sta.addr, sta->llid, sta->plid,
209 sta->reason); 208 sta->reason);
210 spin_unlock_bh(&sta->lock); 209 spin_unlock_bh(&sta->lock);
211 210
212 if (deactivated) 211 ieee80211_bss_info_change_notify(sdata, changed);
213 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
214} 212}
215 213
216static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 214static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
@@ -557,15 +555,14 @@ int mesh_plink_open(struct sta_info *sta)
557void mesh_plink_block(struct sta_info *sta) 555void mesh_plink_block(struct sta_info *sta)
558{ 556{
559 struct ieee80211_sub_if_data *sdata = sta->sdata; 557 struct ieee80211_sub_if_data *sdata = sta->sdata;
560 bool deactivated; 558 u32 changed;
561 559
562 spin_lock_bh(&sta->lock); 560 spin_lock_bh(&sta->lock);
563 deactivated = __mesh_plink_deactivate(sta); 561 changed = __mesh_plink_deactivate(sta);
564 sta->plink_state = NL80211_PLINK_BLOCKED; 562 sta->plink_state = NL80211_PLINK_BLOCKED;
565 spin_unlock_bh(&sta->lock); 563 spin_unlock_bh(&sta->lock);
566 564
567 if (deactivated) 565 ieee80211_bss_info_change_notify(sdata, changed);
568 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
569} 566}
570 567
571 568
@@ -868,9 +865,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
868 del_timer(&sta->plink_timer); 865 del_timer(&sta->plink_timer);
869 sta->plink_state = NL80211_PLINK_ESTAB; 866 sta->plink_state = NL80211_PLINK_ESTAB;
870 spin_unlock_bh(&sta->lock); 867 spin_unlock_bh(&sta->lock);
871 mesh_plink_inc_estab_count(sdata); 868 changed |= mesh_plink_inc_estab_count(sdata);
872 changed |= mesh_set_ht_prot_mode(sdata); 869 changed |= mesh_set_ht_prot_mode(sdata);
873 changed |= BSS_CHANGED_BEACON;
874 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 870 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
875 sta->sta.addr); 871 sta->sta.addr);
876 break; 872 break;
@@ -904,9 +900,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
904 del_timer(&sta->plink_timer); 900 del_timer(&sta->plink_timer);
905 sta->plink_state = NL80211_PLINK_ESTAB; 901 sta->plink_state = NL80211_PLINK_ESTAB;
906 spin_unlock_bh(&sta->lock); 902 spin_unlock_bh(&sta->lock);
907 mesh_plink_inc_estab_count(sdata); 903 changed |= mesh_plink_inc_estab_count(sdata);
908 changed |= mesh_set_ht_prot_mode(sdata); 904 changed |= mesh_set_ht_prot_mode(sdata);
909 changed |= BSS_CHANGED_BEACON;
910 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 905 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
911 sta->sta.addr); 906 sta->sta.addr);
912 mesh_plink_frame_tx(sdata, 907 mesh_plink_frame_tx(sdata,
@@ -924,13 +919,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
924 case CLS_ACPT: 919 case CLS_ACPT:
925 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 920 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
926 sta->reason = reason; 921 sta->reason = reason;
927 __mesh_plink_deactivate(sta); 922 changed |= __mesh_plink_deactivate(sta);
928 sta->plink_state = NL80211_PLINK_HOLDING; 923 sta->plink_state = NL80211_PLINK_HOLDING;
929 llid = sta->llid; 924 llid = sta->llid;
930 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 925 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
931 spin_unlock_bh(&sta->lock); 926 spin_unlock_bh(&sta->lock);
932 changed |= mesh_set_ht_prot_mode(sdata); 927 changed |= mesh_set_ht_prot_mode(sdata);
933 changed |= BSS_CHANGED_BEACON;
934 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 928 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
935 sta->sta.addr, llid, plid, reason); 929 sta->sta.addr, llid, plid, reason);
936 break; 930 break;