diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-01-18 09:48:48 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-01-19 11:36:12 -0500 |
commit | fbb327c5945448e98480d610815143a6d4a63638 (patch) | |
tree | af5148a50e5a7374699c157eb9ef11762f3e0878 /net/mac80211/rx.c | |
parent | 5dd36bc933e8be84f8369ac64505a2938f9ce036 (diff) |
mac80211: drop non-auth 3-addr data frames when running as a 4-addr station
When running as a 4-addr station against an AP that has the 4-addr VLAN
interface and the main 3-addr AP interface bridged together, sometimes
frames originating from the station were looping back from the 3-addr AP
interface, causing the bridge code to emit warnings about receiving frames
with its own source address.
I'm not sure why this is happening yet, but I think it's a good idea to
drop all frames (except 802.1x/EAP frames) that do not match the configured
addressing mode, including 4-address frames sent to a 3-address station.
User test reports indicate that the problem goes away with this patch.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index a6701ed87f0d..1236710f70e0 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1556,17 +1556,36 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1556 | { | 1556 | { |
1557 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1557 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1558 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1558 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
1559 | bool check_port_control = false; | ||
1560 | struct ethhdr *ehdr; | ||
1561 | int ret; | ||
1559 | 1562 | ||
1560 | if (ieee80211_has_a4(hdr->frame_control) && | 1563 | if (ieee80211_has_a4(hdr->frame_control) && |
1561 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) | 1564 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) |
1562 | return -1; | 1565 | return -1; |
1563 | 1566 | ||
1567 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
1568 | !!sdata->u.mgd.use_4addr != !!ieee80211_has_a4(hdr->frame_control)) { | ||
1569 | |||
1570 | if (!sdata->u.mgd.use_4addr) | ||
1571 | return -1; | ||
1572 | else | ||
1573 | check_port_control = true; | ||
1574 | } | ||
1575 | |||
1564 | if (is_multicast_ether_addr(hdr->addr1) && | 1576 | if (is_multicast_ether_addr(hdr->addr1) && |
1565 | ((sdata->vif.type == NL80211_IFTYPE_AP_VLAN && sdata->u.vlan.sta) || | 1577 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && sdata->u.vlan.sta) |
1566 | (sdata->vif.type == NL80211_IFTYPE_STATION && sdata->u.mgd.use_4addr))) | ||
1567 | return -1; | 1578 | return -1; |
1568 | 1579 | ||
1569 | return ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); | 1580 | ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); |
1581 | if (ret < 0 || !check_port_control) | ||
1582 | return ret; | ||
1583 | |||
1584 | ehdr = (struct ethhdr *) rx->skb->data; | ||
1585 | if (ehdr->h_proto != rx->sdata->control_port_protocol) | ||
1586 | return -1; | ||
1587 | |||
1588 | return 0; | ||
1570 | } | 1589 | } |
1571 | 1590 | ||
1572 | /* | 1591 | /* |