aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-04-25 14:34:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-25 14:34:25 -0400
commitcfef6047c4027a8448ec8dafeaf2bb362cc882e4 (patch)
treec254bd25aa8b4b0696b5b5cc45d8e30c7c1bb9dd /net/mac80211/rx.c
parentb71d1d426d263b0b6cb5760322efebbfc89d4463 (diff)
parent73b48099cc265f88fa1255f3f43e52fe6a94fd5c (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/iwlwifi/iwl-core.c drivers/net/wireless/rt2x00/rt2x00queue.c drivers/net/wireless/rt2x00/rt2x00queue.h
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 1f0b010904b8..a864890e4d03 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -143,7 +143,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
143 if (status->flag & RX_FLAG_HT) { 143 if (status->flag & RX_FLAG_HT) {
144 /* 144 /*
145 * MCS information is a separate field in radiotap, 145 * MCS information is a separate field in radiotap,
146 * added below. 146 * added below. The byte here is needed as padding
147 * for the channel though, so initialise it to 0.
147 */ 148 */
148 *pos = 0; 149 *pos = 0;
149 } else { 150 } else {
@@ -502,7 +503,8 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
502 503
503 if (ieee80211_is_probe_req(hdr->frame_control) || 504 if (ieee80211_is_probe_req(hdr->frame_control) ||
504 ieee80211_is_probe_resp(hdr->frame_control) || 505 ieee80211_is_probe_resp(hdr->frame_control) ||
505 ieee80211_is_beacon(hdr->frame_control)) 506 ieee80211_is_beacon(hdr->frame_control) ||
507 ieee80211_is_auth(hdr->frame_control))
506 return RX_CONTINUE; 508 return RX_CONTINUE;
507 509
508 return RX_DROP_MONITOR; 510 return RX_DROP_MONITOR;
@@ -1585,7 +1587,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1585} 1587}
1586 1588
1587static int 1589static int
1588__ieee80211_data_to_8023(struct ieee80211_rx_data *rx) 1590__ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control)
1589{ 1591{
1590 struct ieee80211_sub_if_data *sdata = rx->sdata; 1592 struct ieee80211_sub_if_data *sdata = rx->sdata;
1591 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1593 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
@@ -1593,6 +1595,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1593 struct ethhdr *ehdr; 1595 struct ethhdr *ehdr;
1594 int ret; 1596 int ret;
1595 1597
1598 *port_control = false;
1596 if (ieee80211_has_a4(hdr->frame_control) && 1599 if (ieee80211_has_a4(hdr->frame_control) &&
1597 sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) 1600 sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta)
1598 return -1; 1601 return -1;
@@ -1611,11 +1614,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1611 return -1; 1614 return -1;
1612 1615
1613 ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); 1616 ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type);
1614 if (ret < 0 || !check_port_control) 1617 if (ret < 0)
1615 return ret; 1618 return ret;
1616 1619
1617 ehdr = (struct ethhdr *) rx->skb->data; 1620 ehdr = (struct ethhdr *) rx->skb->data;
1618 if (ehdr->h_proto != rx->sdata->control_port_protocol) 1621 if (ehdr->h_proto == rx->sdata->control_port_protocol)
1622 *port_control = true;
1623 else if (check_port_control)
1619 return -1; 1624 return -1;
1620 1625
1621 return 0; 1626 return 0;
@@ -1916,6 +1921,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1916 struct net_device *dev = sdata->dev; 1921 struct net_device *dev = sdata->dev;
1917 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1922 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1918 __le16 fc = hdr->frame_control; 1923 __le16 fc = hdr->frame_control;
1924 bool port_control;
1919 int err; 1925 int err;
1920 1926
1921 if (unlikely(!ieee80211_is_data(hdr->frame_control))) 1927 if (unlikely(!ieee80211_is_data(hdr->frame_control)))
@@ -1932,13 +1938,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1932 sdata->vif.type == NL80211_IFTYPE_AP) 1938 sdata->vif.type == NL80211_IFTYPE_AP)
1933 return RX_DROP_MONITOR; 1939 return RX_DROP_MONITOR;
1934 1940
1935 err = __ieee80211_data_to_8023(rx); 1941 err = __ieee80211_data_to_8023(rx, &port_control);
1936 if (unlikely(err)) 1942 if (unlikely(err))
1937 return RX_DROP_UNUSABLE; 1943 return RX_DROP_UNUSABLE;
1938 1944
1939 if (!ieee80211_frame_allowed(rx, fc)) 1945 if (!ieee80211_frame_allowed(rx, fc))
1940 return RX_DROP_MONITOR; 1946 return RX_DROP_MONITOR;
1941 1947
1948 if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
1949 unlikely(port_control) && sdata->bss) {
1950 sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
1951 u.ap);
1952 dev = sdata->dev;
1953 rx->sdata = sdata;
1954 }
1955
1942 rx->skb->dev = dev; 1956 rx->skb->dev = dev;
1943 1957
1944 dev->stats.rx_packets++; 1958 dev->stats.rx_packets++;