diff options
-rw-r--r-- | net/mac80211/rx.c | 107 |
1 files changed, 51 insertions, 56 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index a3a26e557274..fab443d717eb 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -352,9 +352,10 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | |||
352 | static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) | 352 | static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) |
353 | { | 353 | { |
354 | #ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT | 354 | #ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT |
355 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | ||
355 | int hdrlen; | 356 | int hdrlen; |
356 | 357 | ||
357 | if (!WLAN_FC_DATA_PRESENT(rx->fc)) | 358 | if (!ieee80211_is_data_present(hdr->frame_control)) |
358 | return; | 359 | return; |
359 | 360 | ||
360 | /* | 361 | /* |
@@ -376,7 +377,7 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) | |||
376 | * header and the payload is not supported, the driver is required | 377 | * header and the payload is not supported, the driver is required |
377 | * to move the 802.11 header further back in that case. | 378 | * to move the 802.11 header further back in that case. |
378 | */ | 379 | */ |
379 | hdrlen = ieee80211_get_hdrlen(rx->fc); | 380 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
380 | if (rx->flags & IEEE80211_RX_AMSDU) | 381 | if (rx->flags & IEEE80211_RX_AMSDU) |
381 | hdrlen += ETH_HLEN; | 382 | hdrlen += ETH_HLEN; |
382 | WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3); | 383 | WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3); |
@@ -415,14 +416,11 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | |||
415 | static ieee80211_rx_result | 416 | static ieee80211_rx_result |
416 | ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | 417 | ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) |
417 | { | 418 | { |
418 | int hdrlen = ieee80211_get_hdrlen(rx->fc); | 419 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
419 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 420 | unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); |
420 | |||
421 | #define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l)) | ||
422 | 421 | ||
423 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { | 422 | if (ieee80211_is_data(hdr->frame_control)) { |
424 | if (!((rx->fc & IEEE80211_FCTL_FROMDS) && | 423 | if (!ieee80211_has_a4(hdr->frame_control)) |
425 | (rx->fc & IEEE80211_FCTL_TODS))) | ||
426 | return RX_DROP_MONITOR; | 424 | return RX_DROP_MONITOR; |
427 | if (memcmp(hdr->addr4, rx->dev->dev_addr, ETH_ALEN) == 0) | 425 | if (memcmp(hdr->addr4, rx->dev->dev_addr, ETH_ALEN) == 0) |
428 | return RX_DROP_MONITOR; | 426 | return RX_DROP_MONITOR; |
@@ -435,27 +433,30 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
435 | if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { | 433 | if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { |
436 | struct ieee80211_mgmt *mgmt; | 434 | struct ieee80211_mgmt *mgmt; |
437 | 435 | ||
438 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) | 436 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
439 | return RX_DROP_MONITOR; | 437 | return RX_DROP_MONITOR; |
440 | 438 | ||
441 | switch (rx->fc & IEEE80211_FCTL_STYPE) { | 439 | if (ieee80211_is_action(hdr->frame_control)) { |
442 | case IEEE80211_STYPE_ACTION: | ||
443 | mgmt = (struct ieee80211_mgmt *)hdr; | 440 | mgmt = (struct ieee80211_mgmt *)hdr; |
444 | if (mgmt->u.action.category != PLINK_CATEGORY) | 441 | if (mgmt->u.action.category != PLINK_CATEGORY) |
445 | return RX_DROP_MONITOR; | 442 | return RX_DROP_MONITOR; |
446 | /* fall through on else */ | ||
447 | case IEEE80211_STYPE_PROBE_REQ: | ||
448 | case IEEE80211_STYPE_PROBE_RESP: | ||
449 | case IEEE80211_STYPE_BEACON: | ||
450 | return RX_CONTINUE; | 443 | return RX_CONTINUE; |
451 | break; | ||
452 | default: | ||
453 | return RX_DROP_MONITOR; | ||
454 | } | 444 | } |
455 | 445 | ||
456 | } else if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && | 446 | if (ieee80211_is_probe_req(hdr->frame_control) || |
457 | is_multicast_ether_addr(hdr->addr1) && | 447 | ieee80211_is_probe_resp(hdr->frame_control) || |
458 | mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->dev)) | 448 | ieee80211_is_beacon(hdr->frame_control)) |
449 | return RX_CONTINUE; | ||
450 | |||
451 | return RX_DROP_MONITOR; | ||
452 | |||
453 | } | ||
454 | |||
455 | #define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l)) | ||
456 | |||
457 | if (ieee80211_is_data(hdr->frame_control) && | ||
458 | is_multicast_ether_addr(hdr->addr1) && | ||
459 | mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->dev)) | ||
459 | return RX_DROP_MONITOR; | 460 | return RX_DROP_MONITOR; |
460 | #undef msh_h_get | 461 | #undef msh_h_get |
461 | 462 | ||
@@ -466,13 +467,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
466 | static ieee80211_rx_result debug_noinline | 467 | static ieee80211_rx_result debug_noinline |
467 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | 468 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) |
468 | { | 469 | { |
469 | struct ieee80211_hdr *hdr; | 470 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
470 | |||
471 | hdr = (struct ieee80211_hdr *) rx->skb->data; | ||
472 | 471 | ||
473 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ | 472 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ |
474 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { | 473 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { |
475 | if (unlikely(rx->fc & IEEE80211_FCTL_RETRY && | 474 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && |
476 | rx->sta->last_seq_ctrl[rx->queue] == | 475 | rx->sta->last_seq_ctrl[rx->queue] == |
477 | hdr->seq_ctrl)) { | 476 | hdr->seq_ctrl)) { |
478 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 477 | if (rx->flags & IEEE80211_RX_RA_MATCH) { |
@@ -501,15 +500,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
501 | if (ieee80211_vif_is_mesh(&rx->sdata->vif)) | 500 | if (ieee80211_vif_is_mesh(&rx->sdata->vif)) |
502 | return ieee80211_rx_mesh_check(rx); | 501 | return ieee80211_rx_mesh_check(rx); |
503 | 502 | ||
504 | if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || | 503 | if (unlikely((ieee80211_is_data(hdr->frame_control) || |
505 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && | 504 | ieee80211_is_pspoll(hdr->frame_control)) && |
506 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && | ||
507 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 505 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
508 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { | 506 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { |
509 | if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && | 507 | if ((!ieee80211_has_fromds(hdr->frame_control) && |
510 | !(rx->fc & IEEE80211_FCTL_TODS) && | 508 | !ieee80211_has_tods(hdr->frame_control) && |
511 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) | 509 | ieee80211_is_data(hdr->frame_control)) || |
512 | || !(rx->flags & IEEE80211_RX_RA_MATCH)) { | 510 | !(rx->flags & IEEE80211_RX_RA_MATCH)) { |
513 | /* Drop IBSS frames and frames for other hosts | 511 | /* Drop IBSS frames and frames for other hosts |
514 | * silently. */ | 512 | * silently. */ |
515 | return RX_DROP_MONITOR; | 513 | return RX_DROP_MONITOR; |
@@ -525,7 +523,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
525 | static ieee80211_rx_result debug_noinline | 523 | static ieee80211_rx_result debug_noinline |
526 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | 524 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) |
527 | { | 525 | { |
528 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 526 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
529 | int keyidx; | 527 | int keyidx; |
530 | int hdrlen; | 528 | int hdrlen; |
531 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | 529 | ieee80211_rx_result result = RX_DROP_UNUSABLE; |
@@ -557,7 +555,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
557 | * possible. | 555 | * possible. |
558 | */ | 556 | */ |
559 | 557 | ||
560 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) | 558 | if (!ieee80211_has_protected(hdr->frame_control)) |
561 | return RX_CONTINUE; | 559 | return RX_CONTINUE; |
562 | 560 | ||
563 | /* | 561 | /* |
@@ -586,7 +584,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
586 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 584 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) |
587 | return RX_CONTINUE; | 585 | return RX_CONTINUE; |
588 | 586 | ||
589 | hdrlen = ieee80211_get_hdrlen(rx->fc); | 587 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
590 | 588 | ||
591 | if (rx->skb->len < 8 + hdrlen) | 589 | if (rx->skb->len < 8 + hdrlen) |
592 | return RX_DROP_UNUSABLE; /* TODO: count this? */ | 590 | return RX_DROP_UNUSABLE; /* TODO: count this? */ |
@@ -618,7 +616,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
618 | 616 | ||
619 | /* Check for weak IVs if possible */ | 617 | /* Check for weak IVs if possible */ |
620 | if (rx->sta && rx->key->conf.alg == ALG_WEP && | 618 | if (rx->sta && rx->key->conf.alg == ALG_WEP && |
621 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 619 | ieee80211_is_data(hdr->frame_control) && |
622 | (!(rx->status->flag & RX_FLAG_IV_STRIPPED) || | 620 | (!(rx->status->flag & RX_FLAG_IV_STRIPPED) || |
623 | !(rx->status->flag & RX_FLAG_DECRYPTED)) && | 621 | !(rx->status->flag & RX_FLAG_DECRYPTED)) && |
624 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | 622 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) |
@@ -710,7 +708,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
710 | { | 708 | { |
711 | struct sta_info *sta = rx->sta; | 709 | struct sta_info *sta = rx->sta; |
712 | struct net_device *dev = rx->dev; | 710 | struct net_device *dev = rx->dev; |
713 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 711 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
714 | 712 | ||
715 | if (!sta) | 713 | if (!sta) |
716 | return RX_CONTINUE; | 714 | return RX_CONTINUE; |
@@ -744,21 +742,20 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
744 | sta->last_qual = rx->status->qual; | 742 | sta->last_qual = rx->status->qual; |
745 | sta->last_noise = rx->status->noise; | 743 | sta->last_noise = rx->status->noise; |
746 | 744 | ||
747 | if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { | 745 | if (!ieee80211_has_morefrags(hdr->frame_control)) { |
748 | /* Change STA power saving mode only in the end of a frame | 746 | /* Change STA power saving mode only in the end of a frame |
749 | * exchange sequence */ | 747 | * exchange sequence */ |
750 | if (test_sta_flags(sta, WLAN_STA_PS) && | 748 | if (test_sta_flags(sta, WLAN_STA_PS) && |
751 | !(rx->fc & IEEE80211_FCTL_PM)) | 749 | !ieee80211_has_pm(hdr->frame_control)) |
752 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); | 750 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); |
753 | else if (!test_sta_flags(sta, WLAN_STA_PS) && | 751 | else if (!test_sta_flags(sta, WLAN_STA_PS) && |
754 | (rx->fc & IEEE80211_FCTL_PM)) | 752 | ieee80211_has_pm(hdr->frame_control)) |
755 | ap_sta_ps_start(dev, sta); | 753 | ap_sta_ps_start(dev, sta); |
756 | } | 754 | } |
757 | 755 | ||
758 | /* Drop data::nullfunc frames silently, since they are used only to | 756 | /* Drop data::nullfunc frames silently, since they are used only to |
759 | * control station power saving mode. */ | 757 | * control station power saving mode. */ |
760 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && | 758 | if (ieee80211_is_nullfunc(hdr->frame_control)) { |
761 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_NULLFUNC) { | ||
762 | I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); | 759 | I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); |
763 | /* Update counter and free packet here to avoid counting this | 760 | /* Update counter and free packet here to avoid counting this |
764 | * as a dropped packed. */ | 761 | * as a dropped packed. */ |
@@ -1465,15 +1462,15 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
1465 | struct ieee80211_local *local = rx->local; | 1462 | struct ieee80211_local *local = rx->local; |
1466 | struct ieee80211_hw *hw = &local->hw; | 1463 | struct ieee80211_hw *hw = &local->hw; |
1467 | struct sk_buff *skb = rx->skb; | 1464 | struct sk_buff *skb = rx->skb; |
1468 | struct ieee80211_bar *bar = (struct ieee80211_bar *) skb->data; | 1465 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; |
1469 | struct tid_ampdu_rx *tid_agg_rx; | 1466 | struct tid_ampdu_rx *tid_agg_rx; |
1470 | u16 start_seq_num; | 1467 | u16 start_seq_num; |
1471 | u16 tid; | 1468 | u16 tid; |
1472 | 1469 | ||
1473 | if (likely((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL)) | 1470 | if (likely(!ieee80211_is_ctl(bar->frame_control))) |
1474 | return RX_CONTINUE; | 1471 | return RX_CONTINUE; |
1475 | 1472 | ||
1476 | if ((rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ) { | 1473 | if (ieee80211_is_back_req(bar->frame_control)) { |
1477 | if (!rx->sta) | 1474 | if (!rx->sta) |
1478 | return RX_CONTINUE; | 1475 | return RX_CONTINUE; |
1479 | tid = le16_to_cpu(bar->control) >> 12; | 1476 | tid = le16_to_cpu(bar->control) >> 12; |
@@ -1527,11 +1524,12 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1527 | struct ieee80211_hdr *hdr, | 1524 | struct ieee80211_hdr *hdr, |
1528 | struct ieee80211_rx_data *rx) | 1525 | struct ieee80211_rx_data *rx) |
1529 | { | 1526 | { |
1530 | int keyidx, hdrlen; | 1527 | int keyidx; |
1528 | unsigned int hdrlen; | ||
1531 | DECLARE_MAC_BUF(mac); | 1529 | DECLARE_MAC_BUF(mac); |
1532 | DECLARE_MAC_BUF(mac2); | 1530 | DECLARE_MAC_BUF(mac2); |
1533 | 1531 | ||
1534 | hdrlen = ieee80211_get_hdrlen_from_skb(rx->skb); | 1532 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1535 | if (rx->skb->len >= hdrlen + 4) | 1533 | if (rx->skb->len >= hdrlen + 4) |
1536 | keyidx = rx->skb->data[hdrlen + 3] >> 6; | 1534 | keyidx = rx->skb->data[hdrlen + 3] >> 6; |
1537 | else | 1535 | else |
@@ -1545,7 +1543,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1545 | goto ignore; | 1543 | goto ignore; |
1546 | } | 1544 | } |
1547 | 1545 | ||
1548 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) | 1546 | if (!ieee80211_has_protected(hdr->frame_control)) |
1549 | goto ignore; | 1547 | goto ignore; |
1550 | 1548 | ||
1551 | if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { | 1549 | if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { |
@@ -1558,9 +1556,8 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1558 | goto ignore; | 1556 | goto ignore; |
1559 | } | 1557 | } |
1560 | 1558 | ||
1561 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && | 1559 | if (!ieee80211_is_data(hdr->frame_control) && |
1562 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || | 1560 | !ieee80211_is_auth(hdr->frame_control)) |
1563 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)) | ||
1564 | goto ignore; | 1561 | goto ignore; |
1565 | 1562 | ||
1566 | mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); | 1563 | mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); |
@@ -1731,8 +1728,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1731 | case IEEE80211_IF_TYPE_IBSS: | 1728 | case IEEE80211_IF_TYPE_IBSS: |
1732 | if (!bssid) | 1729 | if (!bssid) |
1733 | return 0; | 1730 | return 0; |
1734 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && | 1731 | if (ieee80211_is_beacon(hdr->frame_control)) { |
1735 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) { | ||
1736 | if (!rx->sta) | 1732 | if (!rx->sta) |
1737 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, | 1733 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, |
1738 | rx->skb, bssid, hdr->addr2, | 1734 | rx->skb, bssid, hdr->addr2, |
@@ -1783,8 +1779,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1783 | return 0; | 1779 | return 0; |
1784 | break; | 1780 | break; |
1785 | case IEEE80211_IF_TYPE_WDS: | 1781 | case IEEE80211_IF_TYPE_WDS: |
1786 | if (bssid || | 1782 | if (bssid || !ieee80211_is_data(hdr->frame_control)) |
1787 | (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | ||
1788 | return 0; | 1783 | return 0; |
1789 | if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) | 1784 | if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) |
1790 | return 0; | 1785 | return 0; |