mac80211: redirect EAP frames on AP VLAN interfaces to the main AP interface to fix...
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 580-mac80211_redirect_vlan_eap_frames.patch
1 --- a/net/mac80211/rx.c
2 +++ b/net/mac80211/rx.c
3 @@ -1582,7 +1582,7 @@ ieee80211_drop_unencrypted_mgmt(struct i
4 }
5
6 static int
7 -__ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
8 +__ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control)
9 {
10 struct ieee80211_sub_if_data *sdata = rx->sdata;
11 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
12 @@ -1590,6 +1590,7 @@ __ieee80211_data_to_8023(struct ieee8021
13 struct ethhdr *ehdr;
14 int ret;
15
16 + *port_control = false;
17 if (ieee80211_has_a4(hdr->frame_control) &&
18 sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta)
19 return -1;
20 @@ -1608,11 +1609,14 @@ __ieee80211_data_to_8023(struct ieee8021
21 return -1;
22
23 ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type);
24 - if (ret < 0 || !check_port_control)
25 + if (ret < 0)
26 return ret;
27
28 ehdr = (struct ethhdr *) rx->skb->data;
29 - if (ehdr->h_proto != rx->sdata->control_port_protocol)
30 + if (ehdr->h_proto == rx->sdata->control_port_protocol)
31 + *port_control = true;
32 +
33 + if (check_port_control && !*port_control)
34 return -1;
35
36 return 0;
37 @@ -1913,6 +1917,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_
38 struct net_device *dev = sdata->dev;
39 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
40 __le16 fc = hdr->frame_control;
41 + bool port_control;
42 int err;
43
44 if (unlikely(!ieee80211_is_data(hdr->frame_control)))
45 @@ -1929,13 +1934,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_
46 sdata->vif.type == NL80211_IFTYPE_AP)
47 return RX_DROP_MONITOR;
48
49 - err = __ieee80211_data_to_8023(rx);
50 + err = __ieee80211_data_to_8023(rx, &port_control);
51 if (unlikely(err))
52 return RX_DROP_UNUSABLE;
53
54 if (!ieee80211_frame_allowed(rx, fc))
55 return RX_DROP_MONITOR;
56
57 + if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
58 + unlikely(port_control) && sdata->bss) {
59 + sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
60 + u.ap);
61 + dev = sdata->dev;
62 + rx->sdata = sdata;
63 + }
64 +
65 rx->skb->dev = dev;
66
67 dev->stats.rx_packets++;