diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-02-20 19:10:07 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:41:36 -0500 |
commit | 665e8aafb4e0826caec9db25617b186ea3f3ec91 (patch) | |
tree | 156b30cba36776dfd13752f8f51445e3ea11c852 /net | |
parent | 43ba7e958f2ca05e4e9171a15402288419289d71 (diff) |
mac80211: Disallow concurrent IBSS/STA mode interfaces
Disallow having more than one IBSS interface up at any time
because of beacon distribution issues, and for now also disallow
having more than one IBSS/STA interface up at the same time
because we use the master interface's BSS struct which would
be completely corrupted when we have more than one up.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index f82ebdd53d48..2133c9fd27a4 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -183,8 +183,52 @@ static int ieee80211_open(struct net_device *dev) | |||
183 | list_for_each_entry(nsdata, &local->interfaces, list) { | 183 | list_for_each_entry(nsdata, &local->interfaces, list) { |
184 | struct net_device *ndev = nsdata->dev; | 184 | struct net_device *ndev = nsdata->dev; |
185 | 185 | ||
186 | if (ndev != dev && ndev != local->mdev && netif_running(ndev) && | 186 | if (ndev != dev && ndev != local->mdev && netif_running(ndev)) { |
187 | compare_ether_addr(dev->dev_addr, ndev->dev_addr) == 0) { | 187 | /* |
188 | * Allow only a single IBSS interface to be up at any | ||
189 | * time. This is restricted because beacon distribution | ||
190 | * cannot work properly if both are in the same IBSS. | ||
191 | * | ||
192 | * To remove this restriction we'd have to disallow them | ||
193 | * from setting the same SSID on different IBSS interfaces | ||
194 | * belonging to the same hardware. Then, however, we're | ||
195 | * faced with having to adopt two different TSF timers... | ||
196 | */ | ||
197 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | ||
198 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS) | ||
199 | return -EBUSY; | ||
200 | |||
201 | /* | ||
202 | * Disallow multiple IBSS/STA mode interfaces. | ||
203 | * | ||
204 | * This is a technical restriction, it is possible although | ||
205 | * most likely not IEEE 802.11 compliant to have multiple | ||
206 | * STAs with just a single hardware (the TSF timer will not | ||
207 | * be adjusted properly.) | ||
208 | * | ||
209 | * However, because mac80211 uses the master device's BSS | ||
210 | * information for each STA/IBSS interface, doing this will | ||
211 | * currently corrupt that BSS information completely, unless, | ||
212 | * a not very useful case, both STAs are associated to the | ||
213 | * same BSS. | ||
214 | * | ||
215 | * To remove this restriction, the BSS information needs to | ||
216 | * be embedded in the STA/IBSS mode sdata instead of using | ||
217 | * the master device's BSS structure. | ||
218 | */ | ||
219 | if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
220 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) && | ||
221 | (nsdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
222 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS)) | ||
223 | return -EBUSY; | ||
224 | |||
225 | /* | ||
226 | * The remaining checks are only performed for interfaces | ||
227 | * with the same MAC address. | ||
228 | */ | ||
229 | if (compare_ether_addr(dev->dev_addr, ndev->dev_addr)) | ||
230 | continue; | ||
231 | |||
188 | /* | 232 | /* |
189 | * check whether it may have the same address | 233 | * check whether it may have the same address |
190 | */ | 234 | */ |
@@ -196,8 +240,7 @@ static int ieee80211_open(struct net_device *dev) | |||
196 | * can only add VLANs to enabled APs | 240 | * can only add VLANs to enabled APs |
197 | */ | 241 | */ |
198 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && | 242 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && |
199 | nsdata->vif.type == IEEE80211_IF_TYPE_AP && | 243 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) |
200 | netif_running(nsdata->dev)) | ||
201 | sdata->u.vlan.ap = nsdata; | 244 | sdata->u.vlan.ap = nsdata; |
202 | } | 245 | } |
203 | } | 246 | } |