aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-12 09:38:38 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-24 16:27:56 -0400
commit2e161f78e5f63a7f9fd25a766bb7f816a01eb14a (patch)
treebefd44feeb1f47da1f41e6fc310a223ad67030ff /net/mac80211/rx.c
parentac4c977d16d843f12901595c91773dddb65768a9 (diff)
cfg80211/mac80211: extensible frame processing
Allow userspace to register for more than just action frames by giving the frame subtype, and make it possible to use this in various modes as well. With some tweaks and some added functionality this will, in the future, also be usable in AP mode and be able to replace the cooked monitor interface currently used in that case. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c137
1 files changed, 96 insertions, 41 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 4fdbed58ca2f..aa41e382bbb3 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1940,13 +1940,36 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
1940} 1940}
1941 1941
1942static ieee80211_rx_result debug_noinline 1942static ieee80211_rx_result debug_noinline
1943ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
1944{
1945 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
1946
1947 /*
1948 * From here on, look only at management frames.
1949 * Data and control frames are already handled,
1950 * and unknown (reserved) frames are useless.
1951 */
1952 if (rx->skb->len < 24)
1953 return RX_DROP_MONITOR;
1954
1955 if (!ieee80211_is_mgmt(mgmt->frame_control))
1956 return RX_DROP_MONITOR;
1957
1958 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1959 return RX_DROP_MONITOR;
1960
1961 if (ieee80211_drop_unencrypted_mgmt(rx))
1962 return RX_DROP_UNUSABLE;
1963
1964 return RX_CONTINUE;
1965}
1966
1967static ieee80211_rx_result debug_noinline
1943ieee80211_rx_h_action(struct ieee80211_rx_data *rx) 1968ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1944{ 1969{
1945 struct ieee80211_local *local = rx->local; 1970 struct ieee80211_local *local = rx->local;
1946 struct ieee80211_sub_if_data *sdata = rx->sdata; 1971 struct ieee80211_sub_if_data *sdata = rx->sdata;
1947 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; 1972 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
1948 struct sk_buff *nskb;
1949 struct ieee80211_rx_status *status;
1950 int len = rx->skb->len; 1973 int len = rx->skb->len;
1951 1974
1952 if (!ieee80211_is_action(mgmt->frame_control)) 1975 if (!ieee80211_is_action(mgmt->frame_control))
@@ -1962,9 +1985,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1962 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 1985 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1963 return RX_DROP_UNUSABLE; 1986 return RX_DROP_UNUSABLE;
1964 1987
1965 if (ieee80211_drop_unencrypted_mgmt(rx))
1966 return RX_DROP_UNUSABLE;
1967
1968 switch (mgmt->u.action.category) { 1988 switch (mgmt->u.action.category) {
1969 case WLAN_CATEGORY_BACK: 1989 case WLAN_CATEGORY_BACK:
1970 /* 1990 /*
@@ -2055,17 +2075,36 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2055 goto queue; 2075 goto queue;
2056 } 2076 }
2057 2077
2078 return RX_CONTINUE;
2079
2058 invalid: 2080 invalid:
2059 /* 2081 rx->flags |= IEEE80211_MALFORMED_ACTION_FRM;
2060 * For AP mode, hostapd is responsible for handling any action 2082 /* will return in the next handlers */
2061 * frames that we didn't handle, including returning unknown 2083 return RX_CONTINUE;
2062 * ones. For all other modes we will return them to the sender, 2084
2063 * setting the 0x80 bit in the action category, as required by 2085 handled:
2064 * 802.11-2007 7.3.1.11. 2086 if (rx->sta)
2065 */ 2087 rx->sta->rx_packets++;
2066 if (sdata->vif.type == NL80211_IFTYPE_AP || 2088 dev_kfree_skb(rx->skb);
2067 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 2089 return RX_QUEUED;
2068 return RX_DROP_MONITOR; 2090
2091 queue:
2092 rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME;
2093 skb_queue_tail(&sdata->skb_queue, rx->skb);
2094 ieee80211_queue_work(&local->hw, &sdata->work);
2095 if (rx->sta)
2096 rx->sta->rx_packets++;
2097 return RX_QUEUED;
2098}
2099
2100static ieee80211_rx_result debug_noinline
2101ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
2102{
2103 struct ieee80211_rx_status *status;
2104
2105 /* skip known-bad action frames and return them in the next handler */
2106 if (rx->flags & IEEE80211_MALFORMED_ACTION_FRM)
2107 return RX_CONTINUE;
2069 2108
2070 /* 2109 /*
2071 * Getting here means the kernel doesn't know how to handle 2110 * Getting here means the kernel doesn't know how to handle
@@ -2075,10 +2114,44 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2075 */ 2114 */
2076 status = IEEE80211_SKB_RXCB(rx->skb); 2115 status = IEEE80211_SKB_RXCB(rx->skb);
2077 2116
2078 if (cfg80211_rx_action(rx->sdata->dev, status->freq, 2117 if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq,
2079 rx->skb->data, rx->skb->len, 2118 rx->skb->data, rx->skb->len,
2080 GFP_ATOMIC)) 2119 GFP_ATOMIC)) {
2081 goto handled; 2120 if (rx->sta)
2121 rx->sta->rx_packets++;
2122 dev_kfree_skb(rx->skb);
2123 return RX_QUEUED;
2124 }
2125
2126
2127 return RX_CONTINUE;
2128}
2129
2130static ieee80211_rx_result debug_noinline
2131ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
2132{
2133 struct ieee80211_local *local = rx->local;
2134 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
2135 struct sk_buff *nskb;
2136 struct ieee80211_sub_if_data *sdata = rx->sdata;
2137
2138 if (!ieee80211_is_action(mgmt->frame_control))
2139 return RX_CONTINUE;
2140
2141 /*
2142 * For AP mode, hostapd is responsible for handling any action
2143 * frames that we didn't handle, including returning unknown
2144 * ones. For all other modes we will return them to the sender,
2145 * setting the 0x80 bit in the action category, as required by
2146 * 802.11-2007 7.3.1.11.
2147 * Newer versions of hostapd shall also use the management frame
2148 * registration mechanisms, but older ones still use cooked
2149 * monitor interfaces so push all frames there.
2150 */
2151 if (!(rx->flags & IEEE80211_MALFORMED_ACTION_FRM) &&
2152 (sdata->vif.type == NL80211_IFTYPE_AP ||
2153 sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
2154 return RX_DROP_MONITOR;
2082 2155
2083 /* do not return rejected action frames */ 2156 /* do not return rejected action frames */
2084 if (mgmt->u.action.category & 0x80) 2157 if (mgmt->u.action.category & 0x80)
@@ -2097,20 +2170,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2097 2170
2098 ieee80211_tx_skb(rx->sdata, nskb); 2171 ieee80211_tx_skb(rx->sdata, nskb);
2099 } 2172 }
2100
2101 handled:
2102 if (rx->sta)
2103 rx->sta->rx_packets++;
2104 dev_kfree_skb(rx->skb); 2173 dev_kfree_skb(rx->skb);
2105 return RX_QUEUED; 2174 return RX_QUEUED;
2106
2107 queue:
2108 rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME;
2109 skb_queue_tail(&sdata->skb_queue, rx->skb);
2110 ieee80211_queue_work(&local->hw, &sdata->work);
2111 if (rx->sta)
2112 rx->sta->rx_packets++;
2113 return RX_QUEUED;
2114} 2175}
2115 2176
2116static ieee80211_rx_result debug_noinline 2177static ieee80211_rx_result debug_noinline
@@ -2121,15 +2182,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
2121 struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; 2182 struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
2122 __le16 stype; 2183 __le16 stype;
2123 2184
2124 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
2125 return RX_DROP_MONITOR;
2126
2127 if (rx->skb->len < 24)
2128 return RX_DROP_MONITOR;
2129
2130 if (ieee80211_drop_unencrypted_mgmt(rx))
2131 return RX_DROP_UNUSABLE;
2132
2133 rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb); 2185 rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb);
2134 if (rxs != RX_CONTINUE) 2186 if (rxs != RX_CONTINUE)
2135 return rxs; 2187 return rxs;
@@ -2374,7 +2426,10 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
2374 if (res != RX_CONTINUE) 2426 if (res != RX_CONTINUE)
2375 goto rxh_next; 2427 goto rxh_next;
2376 2428
2429 CALL_RXH(ieee80211_rx_h_mgmt_check)
2377 CALL_RXH(ieee80211_rx_h_action) 2430 CALL_RXH(ieee80211_rx_h_action)
2431 CALL_RXH(ieee80211_rx_h_userspace_mgmt)
2432 CALL_RXH(ieee80211_rx_h_action_return)
2378 CALL_RXH(ieee80211_rx_h_mgmt) 2433 CALL_RXH(ieee80211_rx_h_mgmt)
2379 2434
2380 rxh_next: 2435 rxh_next:
@@ -2527,7 +2582,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
2527 break; 2582 break;
2528 case NL80211_IFTYPE_MONITOR: 2583 case NL80211_IFTYPE_MONITOR:
2529 case NL80211_IFTYPE_UNSPECIFIED: 2584 case NL80211_IFTYPE_UNSPECIFIED:
2530 case __NL80211_IFTYPE_AFTER_LAST: 2585 case NUM_NL80211_IFTYPES:
2531 /* should never get here */ 2586 /* should never get here */
2532 WARN_ON(1); 2587 WARN_ON(1);
2533 break; 2588 break;