diff options
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 71 |
1 files changed, 34 insertions, 37 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index e1b34a18b243..75a16853fb45 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -567,18 +567,15 @@ void ieee80211_flush_queues(struct ieee80211_local *local, | |||
567 | IEEE80211_QUEUE_STOP_REASON_FLUSH); | 567 | IEEE80211_QUEUE_STOP_REASON_FLUSH); |
568 | } | 568 | } |
569 | 569 | ||
570 | void ieee80211_iterate_active_interfaces( | 570 | static void __iterate_active_interfaces(struct ieee80211_local *local, |
571 | struct ieee80211_hw *hw, u32 iter_flags, | 571 | u32 iter_flags, |
572 | void (*iterator)(void *data, u8 *mac, | 572 | void (*iterator)(void *data, u8 *mac, |
573 | struct ieee80211_vif *vif), | 573 | struct ieee80211_vif *vif), |
574 | void *data) | 574 | void *data) |
575 | { | 575 | { |
576 | struct ieee80211_local *local = hw_to_local(hw); | ||
577 | struct ieee80211_sub_if_data *sdata; | 576 | struct ieee80211_sub_if_data *sdata; |
578 | 577 | ||
579 | mutex_lock(&local->iflist_mtx); | 578 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
580 | |||
581 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
582 | switch (sdata->vif.type) { | 579 | switch (sdata->vif.type) { |
583 | case NL80211_IFTYPE_MONITOR: | 580 | case NL80211_IFTYPE_MONITOR: |
584 | if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) | 581 | if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) |
@@ -597,13 +594,25 @@ void ieee80211_iterate_active_interfaces( | |||
597 | &sdata->vif); | 594 | &sdata->vif); |
598 | } | 595 | } |
599 | 596 | ||
600 | sdata = rcu_dereference_protected(local->monitor_sdata, | 597 | sdata = rcu_dereference_check(local->monitor_sdata, |
601 | lockdep_is_held(&local->iflist_mtx)); | 598 | lockdep_is_held(&local->iflist_mtx) || |
599 | lockdep_rtnl_is_held()); | ||
602 | if (sdata && | 600 | if (sdata && |
603 | (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || | 601 | (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || |
604 | sdata->flags & IEEE80211_SDATA_IN_DRIVER)) | 602 | sdata->flags & IEEE80211_SDATA_IN_DRIVER)) |
605 | iterator(data, sdata->vif.addr, &sdata->vif); | 603 | iterator(data, sdata->vif.addr, &sdata->vif); |
604 | } | ||
606 | 605 | ||
606 | void ieee80211_iterate_active_interfaces( | ||
607 | struct ieee80211_hw *hw, u32 iter_flags, | ||
608 | void (*iterator)(void *data, u8 *mac, | ||
609 | struct ieee80211_vif *vif), | ||
610 | void *data) | ||
611 | { | ||
612 | struct ieee80211_local *local = hw_to_local(hw); | ||
613 | |||
614 | mutex_lock(&local->iflist_mtx); | ||
615 | __iterate_active_interfaces(local, iter_flags, iterator, data); | ||
607 | mutex_unlock(&local->iflist_mtx); | 616 | mutex_unlock(&local->iflist_mtx); |
608 | } | 617 | } |
609 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); | 618 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); |
@@ -615,38 +624,26 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
615 | void *data) | 624 | void *data) |
616 | { | 625 | { |
617 | struct ieee80211_local *local = hw_to_local(hw); | 626 | struct ieee80211_local *local = hw_to_local(hw); |
618 | struct ieee80211_sub_if_data *sdata; | ||
619 | 627 | ||
620 | rcu_read_lock(); | 628 | rcu_read_lock(); |
629 | __iterate_active_interfaces(local, iter_flags, iterator, data); | ||
630 | rcu_read_unlock(); | ||
631 | } | ||
632 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | ||
621 | 633 | ||
622 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 634 | void ieee80211_iterate_active_interfaces_rtnl( |
623 | switch (sdata->vif.type) { | 635 | struct ieee80211_hw *hw, u32 iter_flags, |
624 | case NL80211_IFTYPE_MONITOR: | 636 | void (*iterator)(void *data, u8 *mac, |
625 | if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) | 637 | struct ieee80211_vif *vif), |
626 | continue; | 638 | void *data) |
627 | break; | 639 | { |
628 | case NL80211_IFTYPE_AP_VLAN: | 640 | struct ieee80211_local *local = hw_to_local(hw); |
629 | continue; | ||
630 | default: | ||
631 | break; | ||
632 | } | ||
633 | if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) && | ||
634 | !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) | ||
635 | continue; | ||
636 | if (ieee80211_sdata_running(sdata)) | ||
637 | iterator(data, sdata->vif.addr, | ||
638 | &sdata->vif); | ||
639 | } | ||
640 | 641 | ||
641 | sdata = rcu_dereference(local->monitor_sdata); | 642 | ASSERT_RTNL(); |
642 | if (sdata && | ||
643 | (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || | ||
644 | sdata->flags & IEEE80211_SDATA_IN_DRIVER)) | ||
645 | iterator(data, sdata->vif.addr, &sdata->vif); | ||
646 | 643 | ||
647 | rcu_read_unlock(); | 644 | __iterate_active_interfaces(local, iter_flags, iterator, data); |
648 | } | 645 | } |
649 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | 646 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl); |
650 | 647 | ||
651 | /* | 648 | /* |
652 | * Nothing should have been stuffed into the workqueue during | 649 | * Nothing should have been stuffed into the workqueue during |