diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-04-12 13:15:22 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-13 15:21:52 -0400 |
commit | 4114fa21465ec7ee9526173676d3122a98bbbbd8 (patch) | |
tree | 761752ef28dd58cc7053b2aff456a49e7362aaca /net/mac80211 | |
parent | 8e26a0303614e766f993b1ac4a5bfbf80436d9dd (diff) |
mac80211: receive EAP frames from a station in an AP VLAN on the main AP
This makes it easier to handle moving stations to VLAN interfaces that are
part of a different bridge.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/rx.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 359fc394a3b0..54858a68abd7 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1586,7 +1586,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) | |||
1586 | } | 1586 | } |
1587 | 1587 | ||
1588 | static int | 1588 | static int |
1589 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | 1589 | __ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control) |
1590 | { | 1590 | { |
1591 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1591 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1592 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1592 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
@@ -1594,6 +1594,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1594 | struct ethhdr *ehdr; | 1594 | struct ethhdr *ehdr; |
1595 | int ret; | 1595 | int ret; |
1596 | 1596 | ||
1597 | *port_control = false; | ||
1597 | if (ieee80211_has_a4(hdr->frame_control) && | 1598 | if (ieee80211_has_a4(hdr->frame_control) && |
1598 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) | 1599 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) |
1599 | return -1; | 1600 | return -1; |
@@ -1612,11 +1613,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1612 | return -1; | 1613 | return -1; |
1613 | 1614 | ||
1614 | ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); | 1615 | ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); |
1615 | if (ret < 0 || !check_port_control) | 1616 | if (ret < 0) |
1616 | return ret; | 1617 | return ret; |
1617 | 1618 | ||
1618 | ehdr = (struct ethhdr *) rx->skb->data; | 1619 | ehdr = (struct ethhdr *) rx->skb->data; |
1619 | if (ehdr->h_proto != rx->sdata->control_port_protocol) | 1620 | if (ehdr->h_proto == rx->sdata->control_port_protocol) |
1621 | *port_control = true; | ||
1622 | else if (check_port_control) | ||
1620 | return -1; | 1623 | return -1; |
1621 | 1624 | ||
1622 | return 0; | 1625 | return 0; |
@@ -1917,6 +1920,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
1917 | struct net_device *dev = sdata->dev; | 1920 | struct net_device *dev = sdata->dev; |
1918 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1921 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
1919 | __le16 fc = hdr->frame_control; | 1922 | __le16 fc = hdr->frame_control; |
1923 | bool port_control; | ||
1920 | int err; | 1924 | int err; |
1921 | 1925 | ||
1922 | if (unlikely(!ieee80211_is_data(hdr->frame_control))) | 1926 | if (unlikely(!ieee80211_is_data(hdr->frame_control))) |
@@ -1933,13 +1937,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
1933 | sdata->vif.type == NL80211_IFTYPE_AP) | 1937 | sdata->vif.type == NL80211_IFTYPE_AP) |
1934 | return RX_DROP_MONITOR; | 1938 | return RX_DROP_MONITOR; |
1935 | 1939 | ||
1936 | err = __ieee80211_data_to_8023(rx); | 1940 | err = __ieee80211_data_to_8023(rx, &port_control); |
1937 | if (unlikely(err)) | 1941 | if (unlikely(err)) |
1938 | return RX_DROP_UNUSABLE; | 1942 | return RX_DROP_UNUSABLE; |
1939 | 1943 | ||
1940 | if (!ieee80211_frame_allowed(rx, fc)) | 1944 | if (!ieee80211_frame_allowed(rx, fc)) |
1941 | return RX_DROP_MONITOR; | 1945 | return RX_DROP_MONITOR; |
1942 | 1946 | ||
1947 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && | ||
1948 | unlikely(port_control) && sdata->bss) { | ||
1949 | sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, | ||
1950 | u.ap); | ||
1951 | dev = sdata->dev; | ||
1952 | rx->sdata = sdata; | ||
1953 | } | ||
1954 | |||
1943 | rx->skb->dev = dev; | 1955 | rx->skb->dev = dev; |
1944 | 1956 | ||
1945 | dev->stats.rx_packets++; | 1957 | dev->stats.rx_packets++; |