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 | |
| 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>
| -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 | } |
