diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 40 |
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 |