diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-07-27 09:43:22 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:47:31 -0400 |
commit | 23a24defa0da567eac615828563935c195fb48dc (patch) | |
tree | dd698a74e0e8a7c3412266f884acb4795a62a0a4 /net/mac80211/rx.c | |
parent | 570bd537a9a1520ddebfed772bcf6eaf7510bec4 (diff) |
[MAC80211]: split up __ieee80211_rx
The really indented part that does the huge switch on the interface
type is a nuisance. Put it into an own function 'prepare_for_handlers'.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 157 |
1 files changed, 83 insertions, 74 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f7a1b61f9bef..21d401523d13 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1240,6 +1240,73 @@ ieee80211_rx_handler ieee80211_rx_handlers[] = | |||
1240 | 1240 | ||
1241 | /* main receive path */ | 1241 | /* main receive path */ |
1242 | 1242 | ||
1243 | static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | ||
1244 | u8 *bssid, struct ieee80211_txrx_data *rx, | ||
1245 | struct ieee80211_hdr *hdr) | ||
1246 | { | ||
1247 | int multicast = is_multicast_ether_addr(hdr->addr1); | ||
1248 | |||
1249 | switch (sdata->type) { | ||
1250 | case IEEE80211_IF_TYPE_STA: | ||
1251 | if (!bssid) | ||
1252 | return 0; | ||
1253 | if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { | ||
1254 | if (!rx->u.rx.in_scan) | ||
1255 | return 0; | ||
1256 | rx->u.rx.ra_match = 0; | ||
1257 | } else if (!multicast && | ||
1258 | compare_ether_addr(sdata->dev->dev_addr, | ||
1259 | hdr->addr1) != 0) { | ||
1260 | if (!sdata->promisc) | ||
1261 | return 0; | ||
1262 | rx->u.rx.ra_match = 0; | ||
1263 | } | ||
1264 | break; | ||
1265 | case IEEE80211_IF_TYPE_IBSS: | ||
1266 | if (!bssid) | ||
1267 | return 0; | ||
1268 | if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { | ||
1269 | if (!rx->u.rx.in_scan) | ||
1270 | return 0; | ||
1271 | rx->u.rx.ra_match = 0; | ||
1272 | } else if (!multicast && | ||
1273 | compare_ether_addr(sdata->dev->dev_addr, | ||
1274 | hdr->addr1) != 0) { | ||
1275 | if (!sdata->promisc) | ||
1276 | return 0; | ||
1277 | rx->u.rx.ra_match = 0; | ||
1278 | } else if (!rx->sta) | ||
1279 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, | ||
1280 | bssid, hdr->addr2); | ||
1281 | break; | ||
1282 | case IEEE80211_IF_TYPE_AP: | ||
1283 | if (!bssid) { | ||
1284 | if (compare_ether_addr(sdata->dev->dev_addr, | ||
1285 | hdr->addr1)) | ||
1286 | return 0; | ||
1287 | } else if (!ieee80211_bssid_match(bssid, | ||
1288 | sdata->dev->dev_addr)) { | ||
1289 | if (!rx->u.rx.in_scan) | ||
1290 | return 0; | ||
1291 | rx->u.rx.ra_match = 0; | ||
1292 | } | ||
1293 | if (sdata->dev == sdata->local->mdev && !rx->u.rx.in_scan) | ||
1294 | /* do not receive anything via | ||
1295 | * master device when not scanning */ | ||
1296 | return 0; | ||
1297 | break; | ||
1298 | case IEEE80211_IF_TYPE_WDS: | ||
1299 | if (bssid || | ||
1300 | (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | ||
1301 | return 0; | ||
1302 | if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) | ||
1303 | return 0; | ||
1304 | break; | ||
1305 | } | ||
1306 | |||
1307 | return 1; | ||
1308 | } | ||
1309 | |||
1243 | /* | 1310 | /* |
1244 | * This is the receive path handler. It is called by a low level driver when an | 1311 | * This is the receive path handler. It is called by a low level driver when an |
1245 | * 802.11 MPDU is received from the hardware. | 1312 | * 802.11 MPDU is received from the hardware. |
@@ -1253,8 +1320,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1253 | struct ieee80211_hdr *hdr; | 1320 | struct ieee80211_hdr *hdr; |
1254 | struct ieee80211_txrx_data rx; | 1321 | struct ieee80211_txrx_data rx; |
1255 | u16 type; | 1322 | u16 type; |
1256 | int multicast; | 1323 | int radiotap_len = 0, prepres; |
1257 | int radiotap_len = 0; | ||
1258 | struct ieee80211_sub_if_data *prev = NULL; | 1324 | struct ieee80211_sub_if_data *prev = NULL; |
1259 | struct sk_buff *skb_new; | 1325 | struct sk_buff *skb_new; |
1260 | u8 *bssid; | 1326 | u8 *bssid; |
@@ -1274,18 +1340,16 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1274 | type = rx.fc & IEEE80211_FCTL_FTYPE; | 1340 | type = rx.fc & IEEE80211_FCTL_FTYPE; |
1275 | if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT) | 1341 | if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT) |
1276 | local->dot11ReceivedFragmentCount++; | 1342 | local->dot11ReceivedFragmentCount++; |
1277 | multicast = is_multicast_ether_addr(hdr->addr1); | ||
1278 | 1343 | ||
1279 | if (skb->len >= 16) | 1344 | if (skb->len >= 16) { |
1280 | sta = rx.sta = sta_info_get(local, hdr->addr2); | 1345 | sta = rx.sta = sta_info_get(local, hdr->addr2); |
1281 | else | 1346 | if (sta) { |
1347 | rx.dev = rx.sta->dev; | ||
1348 | rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev); | ||
1349 | } | ||
1350 | } else | ||
1282 | sta = rx.sta = NULL; | 1351 | sta = rx.sta = NULL; |
1283 | 1352 | ||
1284 | if (sta) { | ||
1285 | rx.dev = sta->dev; | ||
1286 | rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev); | ||
1287 | } | ||
1288 | |||
1289 | if ((status->flag & RX_FLAG_MMIC_ERROR)) { | 1353 | if ((status->flag & RX_FLAG_MMIC_ERROR)) { |
1290 | ieee80211_rx_michael_mic_report(local->mdev, hdr, sta, &rx); | 1354 | ieee80211_rx_michael_mic_report(local->mdev, hdr, sta, &rx); |
1291 | goto end; | 1355 | goto end; |
@@ -1301,10 +1365,10 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1301 | 1365 | ||
1302 | skb_push(skb, radiotap_len); | 1366 | skb_push(skb, radiotap_len); |
1303 | if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS) && | 1367 | if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS) && |
1304 | !local->iff_promiscs && !multicast) { | 1368 | !local->iff_promiscs && !is_multicast_ether_addr(hdr->addr1)) { |
1305 | rx.u.rx.ra_match = 1; | 1369 | rx.u.rx.ra_match = 1; |
1306 | ieee80211_invoke_rx_handlers(local, local->rx_handlers, &rx, | 1370 | ieee80211_invoke_rx_handlers(local, local->rx_handlers, &rx, |
1307 | sta); | 1371 | rx.sta); |
1308 | sta_info_put(sta); | 1372 | sta_info_put(sta); |
1309 | return; | 1373 | return; |
1310 | } | 1374 | } |
@@ -1314,68 +1378,13 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1314 | read_lock(&local->sub_if_lock); | 1378 | read_lock(&local->sub_if_lock); |
1315 | list_for_each_entry(sdata, &local->sub_if_list, list) { | 1379 | list_for_each_entry(sdata, &local->sub_if_list, list) { |
1316 | rx.u.rx.ra_match = 1; | 1380 | rx.u.rx.ra_match = 1; |
1317 | switch (sdata->type) { | 1381 | |
1318 | case IEEE80211_IF_TYPE_STA: | 1382 | prepres = prepare_for_handlers(sdata, bssid, &rx, hdr); |
1319 | if (!bssid) | 1383 | /* prepare_for_handlers can change sta */ |
1320 | continue; | 1384 | sta = rx.sta; |
1321 | if (!ieee80211_bssid_match(bssid, | 1385 | |
1322 | sdata->u.sta.bssid)) { | 1386 | if (!prepres) |
1323 | if (!rx.u.rx.in_scan) | 1387 | continue; |
1324 | continue; | ||
1325 | rx.u.rx.ra_match = 0; | ||
1326 | } else if (!multicast && | ||
1327 | compare_ether_addr(sdata->dev->dev_addr, | ||
1328 | hdr->addr1) != 0) { | ||
1329 | if (!sdata->promisc) | ||
1330 | continue; | ||
1331 | rx.u.rx.ra_match = 0; | ||
1332 | } | ||
1333 | break; | ||
1334 | case IEEE80211_IF_TYPE_IBSS: | ||
1335 | if (!bssid) | ||
1336 | continue; | ||
1337 | if (!ieee80211_bssid_match(bssid, | ||
1338 | sdata->u.sta.bssid)) { | ||
1339 | if (!rx.u.rx.in_scan) | ||
1340 | continue; | ||
1341 | rx.u.rx.ra_match = 0; | ||
1342 | } else if (!multicast && | ||
1343 | compare_ether_addr(sdata->dev->dev_addr, | ||
1344 | hdr->addr1) != 0) { | ||
1345 | if (!sdata->promisc) | ||
1346 | continue; | ||
1347 | rx.u.rx.ra_match = 0; | ||
1348 | } else if (!sta) | ||
1349 | sta = rx.sta = | ||
1350 | ieee80211_ibss_add_sta(sdata->dev, | ||
1351 | skb, bssid, | ||
1352 | hdr->addr2); | ||
1353 | break; | ||
1354 | case IEEE80211_IF_TYPE_AP: | ||
1355 | if (!bssid) { | ||
1356 | if (compare_ether_addr(sdata->dev->dev_addr, | ||
1357 | hdr->addr1)) | ||
1358 | continue; | ||
1359 | } else if (!ieee80211_bssid_match(bssid, | ||
1360 | sdata->dev->dev_addr)) { | ||
1361 | if (!rx.u.rx.in_scan) | ||
1362 | continue; | ||
1363 | rx.u.rx.ra_match = 0; | ||
1364 | } | ||
1365 | if (sdata->dev == local->mdev && !rx.u.rx.in_scan) | ||
1366 | /* do not receive anything via | ||
1367 | * master device when not scanning */ | ||
1368 | continue; | ||
1369 | break; | ||
1370 | case IEEE80211_IF_TYPE_WDS: | ||
1371 | if (bssid || | ||
1372 | (rx.fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | ||
1373 | continue; | ||
1374 | if (compare_ether_addr(sdata->u.wds.remote_addr, | ||
1375 | hdr->addr2)) | ||
1376 | continue; | ||
1377 | break; | ||
1378 | } | ||
1379 | 1388 | ||
1380 | if (prev) { | 1389 | if (prev) { |
1381 | skb_new = skb_copy(skb, GFP_ATOMIC); | 1390 | skb_new = skb_copy(skb, GFP_ATOMIC); |