diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-12-04 17:47:09 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-12-16 05:29:48 -0500 |
commit | 7907c7d33c3733b2265dadc6385fe028af72b4c7 (patch) | |
tree | 820eefc2cecdc675d9346f46e438a19318814ea0 /net/mac80211/key.c | |
parent | e716251d776ce92eb5169522f565ada3deed2a2a (diff) |
mac80211: free all AP/VLAN keys at once
When the AP interface is stopped, free all AP and VLAN keys at
once to only require synchronize_net() once. Since that does
synchronize_net(), also move two such calls into the function
(using the new force_synchronize parameter) to avoid doing it
twice.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r-- | net/mac80211/key.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 12e61543a37c..6ff65a1ebaa9 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -589,14 +589,10 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw, | |||
589 | } | 589 | } |
590 | EXPORT_SYMBOL(ieee80211_iter_keys); | 590 | EXPORT_SYMBOL(ieee80211_iter_keys); |
591 | 591 | ||
592 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) | 592 | static void ieee80211_free_keys_iface(struct ieee80211_sub_if_data *sdata, |
593 | struct list_head *keys) | ||
593 | { | 594 | { |
594 | struct ieee80211_key *key, *tmp; | 595 | struct ieee80211_key *key, *tmp; |
595 | LIST_HEAD(keys); | ||
596 | |||
597 | cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk); | ||
598 | |||
599 | mutex_lock(&sdata->local->key_mtx); | ||
600 | 596 | ||
601 | sdata->crypto_tx_tailroom_needed_cnt -= | 597 | sdata->crypto_tx_tailroom_needed_cnt -= |
602 | sdata->crypto_tx_tailroom_pending_dec; | 598 | sdata->crypto_tx_tailroom_pending_dec; |
@@ -608,21 +604,45 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) | |||
608 | ieee80211_key_replace(key->sdata, key->sta, | 604 | ieee80211_key_replace(key->sdata, key->sta, |
609 | key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, | 605 | key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, |
610 | key, NULL); | 606 | key, NULL); |
611 | list_add_tail(&key->list, &keys); | 607 | list_add_tail(&key->list, keys); |
612 | } | 608 | } |
613 | 609 | ||
614 | ieee80211_debugfs_key_update_default(sdata); | 610 | ieee80211_debugfs_key_update_default(sdata); |
611 | } | ||
615 | 612 | ||
616 | if (!list_empty(&keys)) { | 613 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata, |
617 | synchronize_net(); | 614 | bool force_synchronize) |
618 | list_for_each_entry_safe(key, tmp, &keys, list) | 615 | { |
619 | __ieee80211_key_destroy(key, false); | 616 | struct ieee80211_local *local = sdata->local; |
617 | struct ieee80211_sub_if_data *vlan; | ||
618 | struct ieee80211_key *key, *tmp; | ||
619 | LIST_HEAD(keys); | ||
620 | |||
621 | cancel_delayed_work_sync(&sdata->dec_tailroom_needed_wk); | ||
622 | |||
623 | mutex_lock(&local->key_mtx); | ||
624 | |||
625 | ieee80211_free_keys_iface(sdata, &keys); | ||
626 | |||
627 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
628 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | ||
629 | ieee80211_free_keys_iface(vlan, &keys); | ||
620 | } | 630 | } |
621 | 631 | ||
632 | if (!list_empty(&keys) || force_synchronize) | ||
633 | synchronize_net(); | ||
634 | list_for_each_entry_safe(key, tmp, &keys, list) | ||
635 | __ieee80211_key_destroy(key, false); | ||
636 | |||
622 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || | 637 | WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || |
623 | sdata->crypto_tx_tailroom_pending_dec); | 638 | sdata->crypto_tx_tailroom_pending_dec); |
639 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
640 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | ||
641 | WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt || | ||
642 | vlan->crypto_tx_tailroom_pending_dec); | ||
643 | } | ||
624 | 644 | ||
625 | mutex_unlock(&sdata->local->key_mtx); | 645 | mutex_unlock(&local->key_mtx); |
626 | } | 646 | } |
627 | 647 | ||
628 | void ieee80211_free_sta_keys(struct ieee80211_local *local, | 648 | void ieee80211_free_sta_keys(struct ieee80211_local *local, |