diff options
| author | Johannes Berg <johannes.berg@intel.com> | 2010-06-10 04:21:34 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2010-06-14 15:39:26 -0400 |
| commit | 77a121c3a88eb00a4b5e753d083dbb7d49fefb0a (patch) | |
| tree | d1c802c9133a149094b484cd4796faeb9d7201fb /net/mac80211 | |
| parent | 36b3a628a4e85d002ee8813ebd2a5caef6d3c1a7 (diff) | |
mac80211: pull mgmt frame rx into rx handler
Some code is duplicated between ibss, mesh and
managed mode regarding the queueing of management
frames. Since all modes now use a common skb
queue and a common work function, we can pull
the queueing code into the rx handler directly
and remove the duplicated length checks etc.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
| -rw-r--r-- | net/mac80211/ibss.c | 26 | ||||
| -rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
| -rw-r--r-- | net/mac80211/mesh.c | 25 | ||||
| -rw-r--r-- | net/mac80211/mesh.h | 2 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 27 | ||||
| -rw-r--r-- | net/mac80211/rx.c | 61 |
6 files changed, 48 insertions, 97 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 982690af1f6..bfd7286488c 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -847,32 +847,6 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) | |||
| 847 | mutex_unlock(&local->iflist_mtx); | 847 | mutex_unlock(&local->iflist_mtx); |
| 848 | } | 848 | } |
| 849 | 849 | ||
| 850 | ieee80211_rx_result | ||
| 851 | ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | ||
| 852 | { | ||
| 853 | struct ieee80211_local *local = sdata->local; | ||
| 854 | struct ieee80211_mgmt *mgmt; | ||
| 855 | u16 fc; | ||
| 856 | |||
| 857 | if (skb->len < 24) | ||
| 858 | return RX_DROP_MONITOR; | ||
| 859 | |||
| 860 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
| 861 | fc = le16_to_cpu(mgmt->frame_control); | ||
| 862 | |||
| 863 | switch (fc & IEEE80211_FCTL_STYPE) { | ||
| 864 | case IEEE80211_STYPE_PROBE_RESP: | ||
| 865 | case IEEE80211_STYPE_BEACON: | ||
| 866 | case IEEE80211_STYPE_PROBE_REQ: | ||
| 867 | case IEEE80211_STYPE_AUTH: | ||
| 868 | skb_queue_tail(&sdata->skb_queue, skb); | ||
| 869 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
| 870 | return RX_QUEUED; | ||
| 871 | } | ||
| 872 | |||
| 873 | return RX_DROP_MONITOR; | ||
| 874 | } | ||
| 875 | |||
| 876 | int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | 850 | int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, |
| 877 | struct cfg80211_ibss_params *params) | 851 | struct cfg80211_ibss_params *params) |
| 878 | { | 852 | { |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f8c8f101592..a3bcaa3239d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -981,8 +981,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
| 981 | int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | 981 | int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, |
| 982 | struct cfg80211_disassoc_request *req, | 982 | struct cfg80211_disassoc_request *req, |
| 983 | void *cookie); | 983 | void *cookie); |
| 984 | ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | ||
| 985 | struct sk_buff *skb); | ||
| 986 | void ieee80211_send_pspoll(struct ieee80211_local *local, | 984 | void ieee80211_send_pspoll(struct ieee80211_local *local, |
| 987 | struct ieee80211_sub_if_data *sdata); | 985 | struct ieee80211_sub_if_data *sdata); |
| 988 | void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency); | 986 | void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency); |
| @@ -1002,8 +1000,6 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
| 1002 | /* IBSS code */ | 1000 | /* IBSS code */ |
| 1003 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); | 1001 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); |
| 1004 | void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); | 1002 | void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); |
| 1005 | ieee80211_rx_result | ||
| 1006 | ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | ||
| 1007 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | 1003 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, |
| 1008 | u8 *bssid, u8 *addr, u32 supp_rates, | 1004 | u8 *bssid, u8 *addr, u32 supp_rates, |
| 1009 | gfp_t gfp); | 1005 | gfp_t gfp); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 83b346cc486..c8a4f19ed13 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
| @@ -702,28 +702,3 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) | |||
| 702 | INIT_LIST_HEAD(&ifmsh->preq_queue.list); | 702 | INIT_LIST_HEAD(&ifmsh->preq_queue.list); |
| 703 | spin_lock_init(&ifmsh->mesh_preq_queue_lock); | 703 | spin_lock_init(&ifmsh->mesh_preq_queue_lock); |
| 704 | } | 704 | } |
| 705 | |||
| 706 | ieee80211_rx_result | ||
| 707 | ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | ||
| 708 | { | ||
| 709 | struct ieee80211_local *local = sdata->local; | ||
| 710 | struct ieee80211_mgmt *mgmt; | ||
| 711 | u16 fc; | ||
| 712 | |||
| 713 | if (skb->len < 24) | ||
| 714 | return RX_DROP_MONITOR; | ||
| 715 | |||
| 716 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
| 717 | fc = le16_to_cpu(mgmt->frame_control); | ||
| 718 | |||
| 719 | switch (fc & IEEE80211_FCTL_STYPE) { | ||
| 720 | case IEEE80211_STYPE_ACTION: | ||
| 721 | case IEEE80211_STYPE_PROBE_RESP: | ||
| 722 | case IEEE80211_STYPE_BEACON: | ||
| 723 | skb_queue_tail(&sdata->skb_queue, skb); | ||
| 724 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
| 725 | return RX_QUEUED; | ||
| 726 | } | ||
| 727 | |||
| 728 | return RX_CONTINUE; | ||
| 729 | } | ||
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index c88087f1cd0..ebd3f1d9d88 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
| @@ -237,8 +237,6 @@ void ieee80211s_update_metric(struct ieee80211_local *local, | |||
| 237 | struct sta_info *stainfo, struct sk_buff *skb); | 237 | struct sta_info *stainfo, struct sk_buff *skb); |
| 238 | void ieee80211s_stop(void); | 238 | void ieee80211s_stop(void); |
| 239 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); | 239 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); |
| 240 | ieee80211_rx_result | ||
| 241 | ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | ||
| 242 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); | 240 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); |
| 243 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); | 241 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); |
| 244 | void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh); | 242 | void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4a5b29dac9d..036f1bfa7b0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1633,33 +1633,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
| 1633 | ieee80211_bss_info_change_notify(sdata, changed); | 1633 | ieee80211_bss_info_change_notify(sdata, changed); |
| 1634 | } | 1634 | } |
| 1635 | 1635 | ||
| 1636 | ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | ||
| 1637 | struct sk_buff *skb) | ||
| 1638 | { | ||
| 1639 | struct ieee80211_local *local = sdata->local; | ||
| 1640 | struct ieee80211_mgmt *mgmt; | ||
| 1641 | u16 fc; | ||
| 1642 | |||
| 1643 | if (skb->len < 24) | ||
| 1644 | return RX_DROP_MONITOR; | ||
| 1645 | |||
| 1646 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
| 1647 | fc = le16_to_cpu(mgmt->frame_control); | ||
| 1648 | |||
| 1649 | switch (fc & IEEE80211_FCTL_STYPE) { | ||
| 1650 | case IEEE80211_STYPE_PROBE_RESP: | ||
| 1651 | case IEEE80211_STYPE_BEACON: | ||
| 1652 | case IEEE80211_STYPE_DEAUTH: | ||
| 1653 | case IEEE80211_STYPE_DISASSOC: | ||
| 1654 | case IEEE80211_STYPE_ACTION: | ||
| 1655 | skb_queue_tail(&sdata->skb_queue, skb); | ||
| 1656 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
| 1657 | return RX_QUEUED; | ||
| 1658 | } | ||
| 1659 | |||
| 1660 | return RX_DROP_MONITOR; | ||
| 1661 | } | ||
| 1662 | |||
| 1663 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | 1636 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, |
| 1664 | struct sk_buff *skb) | 1637 | struct sk_buff *skb) |
| 1665 | { | 1638 | { |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 3adcda502b7..40fe2798cbf 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -1950,8 +1950,11 @@ 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) | 1953 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
| 1954 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | 1954 | skb_queue_tail(&sdata->skb_queue, rx->skb); |
| 1955 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
| 1956 | return RX_QUEUED; | ||
| 1957 | } | ||
| 1955 | 1958 | ||
| 1956 | switch (mgmt->u.action.u.addba_req.action_code) { | 1959 | switch (mgmt->u.action.u.addba_req.action_code) { |
| 1957 | case WLAN_ACTION_ADDBA_REQ: | 1960 | case WLAN_ACTION_ADDBA_REQ: |
| @@ -2003,7 +2006,9 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
| 2003 | if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) | 2006 | if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) |
| 2004 | break; | 2007 | break; |
| 2005 | 2008 | ||
| 2006 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | 2009 | skb_queue_tail(&sdata->skb_queue, rx->skb); |
| 2010 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
| 2011 | return RX_QUEUED; | ||
| 2007 | } | 2012 | } |
| 2008 | break; | 2013 | break; |
| 2009 | case WLAN_CATEGORY_SA_QUERY: | 2014 | case WLAN_CATEGORY_SA_QUERY: |
| @@ -2021,9 +2026,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
| 2021 | break; | 2026 | break; |
| 2022 | case WLAN_CATEGORY_MESH_PLINK: | 2027 | case WLAN_CATEGORY_MESH_PLINK: |
| 2023 | case WLAN_CATEGORY_MESH_PATH_SEL: | 2028 | case WLAN_CATEGORY_MESH_PATH_SEL: |
| 2024 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 2029 | if (!ieee80211_vif_is_mesh(&sdata->vif)) |
| 2025 | return ieee80211_mesh_rx_mgmt(sdata, rx->skb); | 2030 | break; |
| 2026 | break; | 2031 | skb_queue_tail(&sdata->skb_queue, rx->skb); |
| 2032 | ieee80211_queue_work(&local->hw, &sdata->work); | ||
| 2033 | return RX_QUEUED; | ||
| 2027 | } | 2034 | } |
| 2028 | 2035 | ||
| 2029 | /* | 2036 | /* |
| @@ -2080,10 +2087,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
| 2080 | { | 2087 | { |
| 2081 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 2088 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
| 2082 | ieee80211_rx_result rxs; | 2089 | ieee80211_rx_result rxs; |
| 2090 | struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; | ||
| 2091 | __le16 stype; | ||
| 2083 | 2092 | ||
| 2084 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 2093 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
| 2085 | return RX_DROP_MONITOR; | 2094 | return RX_DROP_MONITOR; |
| 2086 | 2095 | ||
| 2096 | if (rx->skb->len < 24) | ||
| 2097 | return RX_DROP_MONITOR; | ||
| 2098 | |||
| 2087 | if (ieee80211_drop_unencrypted_mgmt(rx)) | 2099 | if (ieee80211_drop_unencrypted_mgmt(rx)) |
| 2088 | return RX_DROP_UNUSABLE; | 2100 | return RX_DROP_UNUSABLE; |
| 2089 | 2101 | ||
| @@ -2091,16 +2103,39 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
| 2091 | if (rxs != RX_CONTINUE) | 2103 | if (rxs != RX_CONTINUE) |
| 2092 | return rxs; | 2104 | return rxs; |
| 2093 | 2105 | ||
| 2094 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 2106 | stype = mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE); |
| 2095 | return ieee80211_mesh_rx_mgmt(sdata, rx->skb); | ||
| 2096 | 2107 | ||
| 2097 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 2108 | if (!ieee80211_vif_is_mesh(&sdata->vif) && |
| 2098 | return ieee80211_ibss_rx_mgmt(sdata, rx->skb); | 2109 | sdata->vif.type != NL80211_IFTYPE_ADHOC && |
| 2110 | sdata->vif.type != NL80211_IFTYPE_STATION) | ||
| 2111 | return RX_DROP_MONITOR; | ||
| 2099 | 2112 | ||
| 2100 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 2113 | switch (stype) { |
| 2101 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | 2114 | case cpu_to_le16(IEEE80211_STYPE_BEACON): |
| 2115 | case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): | ||
| 2116 | /* process for all: mesh, mlme, ibss */ | ||
| 2117 | break; | ||
| 2118 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): | ||
| 2119 | case cpu_to_le16(IEEE80211_STYPE_DISASSOC): | ||
| 2120 | /* process only for station */ | ||
| 2121 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | ||
| 2122 | return RX_DROP_MONITOR; | ||
| 2123 | break; | ||
| 2124 | case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ): | ||
| 2125 | case cpu_to_le16(IEEE80211_STYPE_AUTH): | ||
| 2126 | /* process only for ibss */ | ||
| 2127 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC) | ||
| 2128 | return RX_DROP_MONITOR; | ||
| 2129 | break; | ||
| 2130 | default: | ||
| 2131 | return RX_DROP_MONITOR; | ||
| 2132 | } | ||
| 2102 | 2133 | ||
| 2103 | return RX_DROP_MONITOR; | 2134 | /* queue up frame and kick off work to process it */ |
| 2135 | skb_queue_tail(&sdata->skb_queue, rx->skb); | ||
| 2136 | ieee80211_queue_work(&rx->local->hw, &sdata->work); | ||
| 2137 | |||
| 2138 | return RX_QUEUED; | ||
| 2104 | } | 2139 | } |
| 2105 | 2140 | ||
| 2106 | static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, | 2141 | static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, |
