aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2015-03-01 02:10:04 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-03-03 09:56:09 -0500
commitc8fff3dc72817d476e083c3f9bc59a11901ecfeb (patch)
treeef86e843cb03fa92654f000b7b7f85e70ac8b023 /net/mac80211/util.c
parentbe72afe0a43825ea357bf61f01ff8fe9938fe7d4 (diff)
mac80211: handle drv_add_interface failures properly during reconfig
If any interface fails to be added to the driver in during reconfig, we should remove all the successfully added interfaces and report reconfig failure, so things can be cleaned up properly. Failing to do so can lead to subsequent failures and leave the drivers in a messed up state. Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index eec94447eef7..327886748a1d 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1811,8 +1811,25 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1811 list_for_each_entry(sdata, &local->interfaces, list) { 1811 list_for_each_entry(sdata, &local->interfaces, list) {
1812 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 1812 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1813 sdata->vif.type != NL80211_IFTYPE_MONITOR && 1813 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
1814 ieee80211_sdata_running(sdata)) 1814 ieee80211_sdata_running(sdata)) {
1815 res = drv_add_interface(local, sdata); 1815 res = drv_add_interface(local, sdata);
1816 if (WARN_ON(res))
1817 break;
1818 }
1819 }
1820
1821 /* If adding any of the interfaces failed above, roll back and
1822 * report failure.
1823 */
1824 if (res) {
1825 list_for_each_entry_continue_reverse(sdata, &local->interfaces,
1826 list)
1827 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1828 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
1829 ieee80211_sdata_running(sdata))
1830 drv_remove_interface(local, sdata);
1831 ieee80211_handle_reconfig_failure(local);
1832 return res;
1816 } 1833 }
1817 1834
1818 /* add channel contexts */ 1835 /* add channel contexts */