aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Porsch <marco.porsch@etit.tu-chemnitz.de>2012-08-08 01:58:43 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-08-13 15:28:34 -0400
commitdf32381896f5f0c78a371df2e49ab7c776b1a5ba (patch)
treed0a5cd8f8a7a6bddfab28c4adc735a65c7b3e696
parentfaa97bd4a43ac69a55029e3b07708bdff0959c07 (diff)
mac80211: fix unnecessary beacon update after peering status change
ieee80211_bss_info_change_notify is called everytime a peer link is established or closed, because the accepting_plinks flag in the meshconf IE *might* have changed. With this patch the corresponding functions return the BSS_CHANGED_BEACON flag when a beacon update is necessary. Also it makes mesh_accept_plinks_update the common place to update the accepting_plinks flag. mesh_accept_plinks_update is called upon plink change and also periodically from ieee80211_mesh_housekeeping. Thus, it also picks up changes of local->num_sta. Signed-off-by: Marco Porsch <marco.porsch@etit.tu-chemnitz.de> Acked-by: Thomas Pedersen <thomas@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-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 6fac18c0423f..856dcf49ce75 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;
@@ -521,14 +527,13 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
521static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, 527static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
522 struct ieee80211_if_mesh *ifmsh) 528 struct ieee80211_if_mesh *ifmsh)
523{ 529{
524 bool free_plinks; 530 u32 changed;
525 531
526 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); 532 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
527 mesh_path_expire(sdata); 533 mesh_path_expire(sdata);
528 534
529 free_plinks = mesh_plink_availables(sdata); 535 changed = mesh_accept_plinks_update(sdata);
530 if (free_plinks != sdata->u.mesh.accepting_plinks) 536 ieee80211_bss_info_change_notify(sdata, changed);
531 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
532 537
533 mod_timer(&ifmsh->housekeeping_timer, 538 mod_timer(&ifmsh->housekeeping_timer,
534 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); 539 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index faaa39bcfd10..13fd5b5fdb0a 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -282,7 +282,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
282 u8 *hw_addr, 282 u8 *hw_addr,
283 struct ieee802_11_elems *ie); 283 struct ieee802_11_elems *ie);
284bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 284bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
285void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 285u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
286void mesh_plink_broken(struct sta_info *sta); 286void mesh_plink_broken(struct sta_info *sta);
287void mesh_plink_deactivate(struct sta_info *sta); 287void mesh_plink_deactivate(struct sta_info *sta);
288int mesh_plink_open(struct sta_info *sta); 288int mesh_plink_open(struct sta_info *sta);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index af671b984df3..f20e9f26d137 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/**
@@ -170,22 +170,21 @@ out:
170 * @sta: mesh peer link to deactivate 170 * @sta: mesh peer link to deactivate
171 * 171 *
172 * All mesh paths with this peer as next hop will be flushed 172 * All mesh paths with this peer as next hop will be flushed
173 * Returns beacon changed flag if the beacon content changed.
173 * 174 *
174 * Locking: the caller must hold sta->lock 175 * Locking: the caller must hold sta->lock
175 */ 176 */
176static bool __mesh_plink_deactivate(struct sta_info *sta) 177static u32 __mesh_plink_deactivate(struct sta_info *sta)
177{ 178{
178 struct ieee80211_sub_if_data *sdata = sta->sdata; 179 struct ieee80211_sub_if_data *sdata = sta->sdata;
179 bool deactivated = false; 180 u32 changed = 0;
180 181
181 if (sta->plink_state == NL80211_PLINK_ESTAB) { 182 if (sta->plink_state == NL80211_PLINK_ESTAB)
182 mesh_plink_dec_estab_count(sdata); 183 changed = mesh_plink_dec_estab_count(sdata);
183 deactivated = true;
184 }
185 sta->plink_state = NL80211_PLINK_BLOCKED; 184 sta->plink_state = NL80211_PLINK_BLOCKED;
186 mesh_path_flush_by_nexthop(sta); 185 mesh_path_flush_by_nexthop(sta);
187 186
188 return deactivated; 187 return changed;
189} 188}
190 189
191/** 190/**
@@ -198,18 +197,17 @@ static bool __mesh_plink_deactivate(struct sta_info *sta)
198void mesh_plink_deactivate(struct sta_info *sta) 197void mesh_plink_deactivate(struct sta_info *sta)
199{ 198{
200 struct ieee80211_sub_if_data *sdata = sta->sdata; 199 struct ieee80211_sub_if_data *sdata = sta->sdata;
201 bool deactivated; 200 u32 changed;
202 201
203 spin_lock_bh(&sta->lock); 202 spin_lock_bh(&sta->lock);
204 deactivated = __mesh_plink_deactivate(sta); 203 changed = __mesh_plink_deactivate(sta);
205 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED); 204 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED);
206 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 205 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
207 sta->sta.addr, sta->llid, sta->plid, 206 sta->sta.addr, sta->llid, sta->plid,
208 sta->reason); 207 sta->reason);
209 spin_unlock_bh(&sta->lock); 208 spin_unlock_bh(&sta->lock);
210 209
211 if (deactivated) 210 ieee80211_bss_info_change_notify(sdata, changed);
212 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
213} 211}
214 212
215static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 213static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
@@ -541,15 +539,14 @@ int mesh_plink_open(struct sta_info *sta)
541void mesh_plink_block(struct sta_info *sta) 539void mesh_plink_block(struct sta_info *sta)
542{ 540{
543 struct ieee80211_sub_if_data *sdata = sta->sdata; 541 struct ieee80211_sub_if_data *sdata = sta->sdata;
544 bool deactivated; 542 u32 changed;
545 543
546 spin_lock_bh(&sta->lock); 544 spin_lock_bh(&sta->lock);
547 deactivated = __mesh_plink_deactivate(sta); 545 changed = __mesh_plink_deactivate(sta);
548 sta->plink_state = NL80211_PLINK_BLOCKED; 546 sta->plink_state = NL80211_PLINK_BLOCKED;
549 spin_unlock_bh(&sta->lock); 547 spin_unlock_bh(&sta->lock);
550 548
551 if (deactivated) 549 ieee80211_bss_info_change_notify(sdata, changed);
552 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
553} 550}
554 551
555 552
@@ -852,9 +849,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
852 del_timer(&sta->plink_timer); 849 del_timer(&sta->plink_timer);
853 sta->plink_state = NL80211_PLINK_ESTAB; 850 sta->plink_state = NL80211_PLINK_ESTAB;
854 spin_unlock_bh(&sta->lock); 851 spin_unlock_bh(&sta->lock);
855 mesh_plink_inc_estab_count(sdata); 852 changed |= mesh_plink_inc_estab_count(sdata);
856 changed |= mesh_set_ht_prot_mode(sdata); 853 changed |= mesh_set_ht_prot_mode(sdata);
857 changed |= BSS_CHANGED_BEACON;
858 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 854 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
859 sta->sta.addr); 855 sta->sta.addr);
860 break; 856 break;
@@ -888,9 +884,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
888 del_timer(&sta->plink_timer); 884 del_timer(&sta->plink_timer);
889 sta->plink_state = NL80211_PLINK_ESTAB; 885 sta->plink_state = NL80211_PLINK_ESTAB;
890 spin_unlock_bh(&sta->lock); 886 spin_unlock_bh(&sta->lock);
891 mesh_plink_inc_estab_count(sdata); 887 changed |= mesh_plink_inc_estab_count(sdata);
892 changed |= mesh_set_ht_prot_mode(sdata); 888 changed |= mesh_set_ht_prot_mode(sdata);
893 changed |= BSS_CHANGED_BEACON;
894 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 889 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
895 sta->sta.addr); 890 sta->sta.addr);
896 mesh_plink_frame_tx(sdata, 891 mesh_plink_frame_tx(sdata,
@@ -908,13 +903,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
908 case CLS_ACPT: 903 case CLS_ACPT:
909 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 904 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
910 sta->reason = reason; 905 sta->reason = reason;
911 __mesh_plink_deactivate(sta); 906 changed |= __mesh_plink_deactivate(sta);
912 sta->plink_state = NL80211_PLINK_HOLDING; 907 sta->plink_state = NL80211_PLINK_HOLDING;
913 llid = sta->llid; 908 llid = sta->llid;
914 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 909 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
915 spin_unlock_bh(&sta->lock); 910 spin_unlock_bh(&sta->lock);
916 changed |= mesh_set_ht_prot_mode(sdata); 911 changed |= mesh_set_ht_prot_mode(sdata);
917 changed |= BSS_CHANGED_BEACON;
918 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 912 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
919 sta->sta.addr, llid, plid, reason); 913 sta->sta.addr, llid, plid, reason);
920 break; 914 break;