aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 28316b2a585f..6bce97ee2534 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -507,7 +507,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
507 507
508 if (ieee80211_is_action(hdr->frame_control)) { 508 if (ieee80211_is_action(hdr->frame_control)) {
509 mgmt = (struct ieee80211_mgmt *)hdr; 509 mgmt = (struct ieee80211_mgmt *)hdr;
510 if (mgmt->u.action.category != PLINK_CATEGORY) 510 if (mgmt->u.action.category != MESH_PLINK_CATEGORY)
511 return RX_DROP_MONITOR; 511 return RX_DROP_MONITOR;
512 return RX_CONTINUE; 512 return RX_CONTINUE;
513 } 513 }
@@ -1181,6 +1181,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1181{ 1181{
1182 struct net_device *dev = rx->dev; 1182 struct net_device *dev = rx->dev;
1183 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1183 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1184 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1185
1186 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->use_4addr &&
1187 ieee80211_has_a4(hdr->frame_control))
1188 return -1;
1189 if (sdata->use_4addr && is_multicast_ether_addr(hdr->addr1))
1190 return -1;
1184 1191
1185 return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type); 1192 return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type);
1186} 1193}
@@ -1229,7 +1236,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1229 if ((sdata->vif.type == NL80211_IFTYPE_AP || 1236 if ((sdata->vif.type == NL80211_IFTYPE_AP ||
1230 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && 1237 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
1231 !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && 1238 !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
1232 (rx->flags & IEEE80211_RX_RA_MATCH)) { 1239 (rx->flags & IEEE80211_RX_RA_MATCH) && !rx->sdata->use_4addr) {
1233 if (is_multicast_ether_addr(ehdr->h_dest)) { 1240 if (is_multicast_ether_addr(ehdr->h_dest)) {
1234 /* 1241 /*
1235 * send multicast frames both to higher layers in 1242 * send multicast frames both to higher layers in
@@ -1534,6 +1541,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1534{ 1541{
1535 struct net_device *dev = rx->dev; 1542 struct net_device *dev = rx->dev;
1536 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1543 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1544 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1537 __le16 fc = hdr->frame_control; 1545 __le16 fc = hdr->frame_control;
1538 int err; 1546 int err;
1539 1547
@@ -1543,6 +1551,14 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1543 if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) 1551 if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
1544 return RX_DROP_MONITOR; 1552 return RX_DROP_MONITOR;
1545 1553
1554 /*
1555 * Allow the cooked monitor interface of an AP to see 4-addr frames so
1556 * that a 4-addr station can be detected and moved into a separate VLAN
1557 */
1558 if (ieee80211_has_a4(hdr->frame_control) &&
1559 sdata->vif.type == NL80211_IFTYPE_AP)
1560 return RX_DROP_MONITOR;
1561
1546 err = __ieee80211_data_to_8023(rx); 1562 err = __ieee80211_data_to_8023(rx);
1547 if (unlikely(err)) 1563 if (unlikely(err))
1548 return RX_DROP_UNUSABLE; 1564 return RX_DROP_UNUSABLE;
@@ -1983,7 +1999,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1983 1999
1984 switch (sdata->vif.type) { 2000 switch (sdata->vif.type) {
1985 case NL80211_IFTYPE_STATION: 2001 case NL80211_IFTYPE_STATION:
1986 if (!bssid) 2002 if (!bssid && !sdata->use_4addr)
1987 return 0; 2003 return 0;
1988 if (!multicast && 2004 if (!multicast &&
1989 compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) { 2005 compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) {
@@ -2425,9 +2441,21 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2425 goto drop; 2441 goto drop;
2426 2442
2427 if (status->flag & RX_FLAG_HT) { 2443 if (status->flag & RX_FLAG_HT) {
2428 /* rate_idx is MCS index */ 2444 /*
2429 if (WARN_ON(status->rate_idx < 0 || 2445 * rate_idx is MCS index, which can be [0-76] as documented on:
2430 status->rate_idx >= 76)) 2446 *
2447 * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n
2448 *
2449 * Anything else would be some sort of driver or hardware error.
2450 * The driver should catch hardware errors.
2451 */
2452 if (WARN((status->rate_idx < 0 ||
2453 status->rate_idx > 76),
2454 "Rate marked as an HT rate but passed "
2455 "status->rate_idx is not "
2456 "an MCS index [0-76]: %d (0x%02x)\n",
2457 status->rate_idx,
2458 status->rate_idx))
2431 goto drop; 2459 goto drop;
2432 /* HT rates are not in the table - use the highest legacy rate 2460 /* HT rates are not in the table - use the highest legacy rate
2433 * for now since other parts of mac80211 may not yet be fully 2461 * for now since other parts of mac80211 may not yet be fully