diff options
| -rw-r--r-- | net/mac80211/iface.c | 31 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 38 | ||||
| -rw-r--r-- | net/mac80211/rx.c | 29 |
3 files changed, 43 insertions, 55 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 1bf276d7024..7a3dbde9979 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -724,7 +724,36 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
| 724 | 724 | ||
| 725 | /* first process frames */ | 725 | /* first process frames */ |
| 726 | while ((skb = skb_dequeue(&sdata->skb_queue))) { | 726 | while ((skb = skb_dequeue(&sdata->skb_queue))) { |
| 727 | switch (sdata->vif.type) { | 727 | struct ieee80211_mgmt *mgmt = (void *)skb->data; |
| 728 | |||
| 729 | if (ieee80211_is_action(mgmt->frame_control) && | ||
| 730 | mgmt->u.action.category == WLAN_CATEGORY_BACK) { | ||
| 731 | int len = skb->len; | ||
| 732 | struct sta_info *sta; | ||
| 733 | |||
| 734 | rcu_read_lock(); | ||
| 735 | sta = sta_info_get(sdata, mgmt->sa); | ||
| 736 | if (sta) { | ||
| 737 | switch (mgmt->u.action.u.addba_req.action_code) { | ||
| 738 | case WLAN_ACTION_ADDBA_REQ: | ||
| 739 | ieee80211_process_addba_request( | ||
| 740 | local, sta, mgmt, len); | ||
| 741 | break; | ||
| 742 | case WLAN_ACTION_ADDBA_RESP: | ||
| 743 | ieee80211_process_addba_resp(local, sta, | ||
| 744 | mgmt, len); | ||
| 745 | break; | ||
| 746 | case WLAN_ACTION_DELBA: | ||
| 747 | ieee80211_process_delba(sdata, sta, | ||
| 748 | mgmt, len); | ||
| 749 | break; | ||
| 750 | default: | ||
| 751 | WARN_ON(1); | ||
| 752 | break; | ||
| 753 | } | ||
| 754 | } | ||
| 755 | rcu_read_unlock(); | ||
| 756 | } else switch (sdata->vif.type) { | ||
| 728 | case NL80211_IFTYPE_STATION: | 757 | case NL80211_IFTYPE_STATION: |
| 729 | ieee80211_sta_rx_queued_mgmt(sdata, skb); | 758 | ieee80211_sta_rx_queued_mgmt(sdata, skb); |
| 730 | break; | 759 | break; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 036f1bfa7b0..583b34686a2 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1666,44 +1666,6 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
| 1666 | break; | 1666 | break; |
| 1667 | case IEEE80211_STYPE_ACTION: | 1667 | case IEEE80211_STYPE_ACTION: |
| 1668 | switch (mgmt->u.action.category) { | 1668 | switch (mgmt->u.action.category) { |
| 1669 | case WLAN_CATEGORY_BACK: { | ||
| 1670 | struct ieee80211_local *local = sdata->local; | ||
| 1671 | int len = skb->len; | ||
| 1672 | struct sta_info *sta; | ||
| 1673 | |||
| 1674 | rcu_read_lock(); | ||
| 1675 | sta = sta_info_get(sdata, mgmt->sa); | ||
| 1676 | if (!sta) { | ||
| 1677 | rcu_read_unlock(); | ||
| 1678 | break; | ||
| 1679 | } | ||
| 1680 | |||
| 1681 | local_bh_disable(); | ||
| 1682 | |||
| 1683 | switch (mgmt->u.action.u.addba_req.action_code) { | ||
| 1684 | case WLAN_ACTION_ADDBA_REQ: | ||
| 1685 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 1686 | sizeof(mgmt->u.action.u.addba_req))) | ||
| 1687 | break; | ||
| 1688 | ieee80211_process_addba_request(local, sta, mgmt, len); | ||
| 1689 | break; | ||
| 1690 | case WLAN_ACTION_ADDBA_RESP: | ||
| 1691 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 1692 | sizeof(mgmt->u.action.u.addba_resp))) | ||
| 1693 | break; | ||
| 1694 | ieee80211_process_addba_resp(local, sta, mgmt, len); | ||
| 1695 | break; | ||
| 1696 | case WLAN_ACTION_DELBA: | ||
| 1697 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 1698 | sizeof(mgmt->u.action.u.delba))) | ||
| 1699 | break; | ||
| 1700 | ieee80211_process_delba(sdata, sta, mgmt, len); | ||
| 1701 | break; | ||
| 1702 | } | ||
| 1703 | local_bh_enable(); | ||
| 1704 | rcu_read_unlock(); | ||
| 1705 | break; | ||
| 1706 | } | ||
| 1707 | case WLAN_CATEGORY_SPECTRUM_MGMT: | 1669 | case WLAN_CATEGORY_SPECTRUM_MGMT: |
| 1708 | ieee80211_sta_process_chanswitch(sdata, | 1670 | ieee80211_sta_process_chanswitch(sdata, |
| 1709 | &mgmt->u.action.u.chan_switch.sw_elem, | 1671 | &mgmt->u.action.u.chan_switch.sw_elem, |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 40fe2798cbf..435c2166e0c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -1950,33 +1950,29 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
| 1950 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | 1950 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) |
| 1951 | break; | 1951 | break; |
| 1952 | 1952 | ||
| 1953 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
| 1954 | skb_queue_tail(&sdata->skb_queue, rx->skb); | ||
| 1955 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
| 1956 | return RX_QUEUED; | ||
| 1957 | } | ||
| 1958 | |||
| 1959 | switch (mgmt->u.action.u.addba_req.action_code) { | 1953 | switch (mgmt->u.action.u.addba_req.action_code) { |
| 1960 | case WLAN_ACTION_ADDBA_REQ: | 1954 | case WLAN_ACTION_ADDBA_REQ: |
| 1961 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1955 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
| 1962 | sizeof(mgmt->u.action.u.addba_req))) | 1956 | sizeof(mgmt->u.action.u.addba_req))) |
| 1963 | return RX_DROP_MONITOR; | 1957 | goto invalid; |
| 1964 | ieee80211_process_addba_request(local, rx->sta, mgmt, len); | 1958 | break; |
| 1965 | goto handled; | ||
| 1966 | case WLAN_ACTION_ADDBA_RESP: | 1959 | case WLAN_ACTION_ADDBA_RESP: |
| 1967 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1960 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
| 1968 | sizeof(mgmt->u.action.u.addba_resp))) | 1961 | sizeof(mgmt->u.action.u.addba_resp))) |
| 1969 | break; | 1962 | goto invalid; |
| 1970 | ieee80211_process_addba_resp(local, rx->sta, mgmt, len); | 1963 | break; |
| 1971 | goto handled; | ||
| 1972 | case WLAN_ACTION_DELBA: | 1964 | case WLAN_ACTION_DELBA: |
| 1973 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1965 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
| 1974 | sizeof(mgmt->u.action.u.delba))) | 1966 | sizeof(mgmt->u.action.u.delba))) |
| 1975 | break; | 1967 | goto invalid; |
| 1976 | ieee80211_process_delba(sdata, rx->sta, mgmt, len); | 1968 | break; |
| 1977 | goto handled; | 1969 | default: |
| 1970 | goto invalid; | ||
| 1978 | } | 1971 | } |
| 1979 | break; | 1972 | |
| 1973 | skb_queue_tail(&sdata->skb_queue, rx->skb); | ||
| 1974 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
| 1975 | return RX_QUEUED; | ||
| 1980 | case WLAN_CATEGORY_SPECTRUM_MGMT: | 1976 | case WLAN_CATEGORY_SPECTRUM_MGMT: |
| 1981 | if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ) | 1977 | if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ) |
| 1982 | break; | 1978 | break; |
| @@ -2033,6 +2029,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
| 2033 | return RX_QUEUED; | 2029 | return RX_QUEUED; |
| 2034 | } | 2030 | } |
| 2035 | 2031 | ||
| 2032 | invalid: | ||
| 2036 | /* | 2033 | /* |
| 2037 | * For AP mode, hostapd is responsible for handling any action | 2034 | * For AP mode, hostapd is responsible for handling any action |
| 2038 | * frames that we didn't handle, including returning unknown | 2035 | * frames that we didn't handle, including returning unknown |
