Search Linux Wireless

[RFT] mac80211: allow mode changes while interface is up

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It might be nicer sometimes to allow mode changes while the
interface is up, e.g. from managed to ibss mode, so that IP
configuration is retained. This patch changes mac80211 to
support that, it effectively internally behaves as though
you had actually done a down/change/up cycle.

Signed-off-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>
---
COMPLETELY UNTESTED. If anyone needs this functionality
please test and adopt this patch -- I have no interest in
pushing it into the kernel.

 net/mac80211/iface.c |   36 +++++++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 11 deletions(-)

--- wireless-testing.orig/net/mac80211/iface.c	2009-03-21 17:20:23.000000000 +0100
+++ wireless-testing/net/mac80211/iface.c	2009-03-21 17:26:59.000000000 +0100
@@ -749,24 +749,22 @@ static void ieee80211_setup_sdata(struct
 int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
 			     enum nl80211_iftype type)
 {
-	ASSERT_RTNL();
+	int ret = 0;
+	bool running = false;
+	enum nl80211_iftype oldtype;
 
-	if (type == sdata->vif.type)
-		return 0;
+	ASSERT_RTNL();
 
 	/* Setting ad-hoc mode on non-IBSS channel is not supported. */
 	if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS &&
 	    type == NL80211_IFTYPE_ADHOC)
 		return -EOPNOTSUPP;
 
-	/*
-	 * We could, here, on changes between IBSS/STA/MESH modes,
-	 * invoke an MLME function instead that disassociates etc.
-	 * and goes into the requested mode.
-	 */
+	oldtype = sdata->vif.type;
+	running = netif_running(sdata->dev);
 
-	if (netif_running(sdata->dev))
-		return -EBUSY;
+	if (running)
+		ieee80211_stop(sdata->dev);
 
 	/* Purge and reset type-dependent state. */
 	ieee80211_teardown_sdata(sdata->dev);
@@ -778,7 +776,23 @@ int ieee80211_if_change_type(struct ieee
 			sdata->local->hw.conf.channel->band);
 	sdata->drop_unencrypted = 0;
 
-	return 0;
+	if (running) {
+		ret = ieee80211_open(sdata->dev);
+		if (ret) {
+			/*
+			 * ieee80211_open could fail, for example if the user
+			 * wants to have an interface combination now that we
+			 * do not support -- in that case roll back. This has
+			 * to succeed unless we have a driver/mac80211 bug,
+			 * since the interface was there before!
+			 */
+			ieee80211_teardown_sdata(sdata->dev);
+			ieee80211_setup_sdata(sdata, oldtype);
+			WARN_ON(ieee80211_open(sdata->dev));
+		}
+	}
+
+	return ret;
 }
 
 int ieee80211_if_add(struct ieee80211_local *local, const char *name,


--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux