diff options
author | Johannes Berg <johannes.berg@intel.com> | 2014-01-29 07:28:02 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-02-06 03:55:22 -0500 |
commit | fab57a6cc227468ca9e6a4c7ff8d3b10727785ee (patch) | |
tree | 2b0c3ea40b1a652105eefc22032046fd59a0ad0f /net/mac80211/iface.c | |
parent | 338f977f4eb441e69bb9a46eaa0ac715c931a67f (diff) |
mac80211: fix virtual monitor interface iteration
During channel context assignment, the interface should
be found by interface iteration, so we need to assign the
pointer before the channel context.
Reported-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Tested-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ae2eb148a028..d6d1f1df9119 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -418,20 +418,24 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
418 | return ret; | 418 | return ret; |
419 | } | 419 | } |
420 | 420 | ||
421 | mutex_lock(&local->iflist_mtx); | ||
422 | rcu_assign_pointer(local->monitor_sdata, sdata); | ||
423 | mutex_unlock(&local->iflist_mtx); | ||
424 | |||
421 | mutex_lock(&local->mtx); | 425 | mutex_lock(&local->mtx); |
422 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, | 426 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, |
423 | IEEE80211_CHANCTX_EXCLUSIVE); | 427 | IEEE80211_CHANCTX_EXCLUSIVE); |
424 | mutex_unlock(&local->mtx); | 428 | mutex_unlock(&local->mtx); |
425 | if (ret) { | 429 | if (ret) { |
430 | mutex_lock(&local->iflist_mtx); | ||
431 | rcu_assign_pointer(local->monitor_sdata, NULL); | ||
432 | mutex_unlock(&local->iflist_mtx); | ||
433 | synchronize_net(); | ||
426 | drv_remove_interface(local, sdata); | 434 | drv_remove_interface(local, sdata); |
427 | kfree(sdata); | 435 | kfree(sdata); |
428 | return ret; | 436 | return ret; |
429 | } | 437 | } |
430 | 438 | ||
431 | mutex_lock(&local->iflist_mtx); | ||
432 | rcu_assign_pointer(local->monitor_sdata, sdata); | ||
433 | mutex_unlock(&local->iflist_mtx); | ||
434 | |||
435 | return 0; | 439 | return 0; |
436 | } | 440 | } |
437 | 441 | ||