aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_iface.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-02-25 10:27:49 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-06 15:30:47 -0500
commit44213b5e13c907bf4aa2e73941944f90184c8772 (patch)
treedb680fc6b4913b072a8f85cf0fac622aea2edb5d /net/mac80211/ieee80211_iface.c
parent693b1bbcc47b3fd436068f294147357f90cd1296 (diff)
mac80211: remove STA entries when taking down interface
When we take down an interface, we need to remove the STA info items that belong to it because otherwise we might invoke a sta_notify() callback in the driver when we later delete the STA entries, but in that case the driver will already have removed its knowledge of the interface they belonged to leading to confusion. Also, we could invoke the set_tim() callback after the driver removed its knowledge of the interface, which can lead to a crash if it requests a beacon with a then-invalid vif pointer! A side effect of this patch is that, because it was easier, it disallows changing the WDS peer while an interface is up. Should that actually be necessary, it can be added back, but the WDS peer STA entry may not be added while the interface is UP so for now I've simplified the WDS peer's STA entry lifetime management. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ieee80211_iface.c')
-rw-r--r--net/mac80211/ieee80211_iface.c22
1 files changed, 4 insertions, 18 deletions
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index 98b22736e883..80954a512185 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -187,8 +187,8 @@ void ieee80211_if_reinit(struct net_device *dev)
187{ 187{
188 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 188 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
189 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 189 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
190 struct sta_info *sta;
191 struct sk_buff *skb; 190 struct sk_buff *skb;
191 int flushed;
192 192
193 ASSERT_RTNL(); 193 ASSERT_RTNL();
194 194
@@ -240,21 +240,7 @@ void ieee80211_if_reinit(struct net_device *dev)
240 break; 240 break;
241 } 241 }
242 case IEEE80211_IF_TYPE_WDS: 242 case IEEE80211_IF_TYPE_WDS:
243 rcu_read_lock(); 243 /* nothing to do */
244 sta = sta_info_get(local, sdata->u.wds.remote_addr);
245 if (sta) {
246 sta_info_unlink(&sta);
247 } else {
248#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
249 printk(KERN_DEBUG "%s: Someone had deleted my STA "
250 "entry for the WDS link\n", dev->name);
251#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
252 }
253 rcu_read_unlock();
254 if (sta) {
255 synchronize_rcu();
256 sta_info_destroy(sta);
257 }
258 break; 244 break;
259 case IEEE80211_IF_TYPE_MESH_POINT: 245 case IEEE80211_IF_TYPE_MESH_POINT:
260 case IEEE80211_IF_TYPE_STA: 246 case IEEE80211_IF_TYPE_STA:
@@ -279,8 +265,8 @@ void ieee80211_if_reinit(struct net_device *dev)
279 break; 265 break;
280 } 266 }
281 267
282 /* remove all STAs that are bound to this virtual interface */ 268 flushed = sta_info_flush(local, sdata);
283 sta_info_flush(local, sdata); 269 WARN_ON(flushed);
284 270
285 memset(&sdata->u, 0, sizeof(sdata->u)); 271 memset(&sdata->u, 0, sizeof(sdata->u));
286 ieee80211_if_sdata_init(sdata); 272 ieee80211_if_sdata_init(sdata);