4c5b403dc4b19cefe5e8c0a475af9114de2fee7e
[oweals/openwrt.git] /
1 From 3ad31f4efe9674a8bda057c79995a9468281e77f Mon Sep 17 00:00:00 2001
2 From: Manikanta Pubbisetty <mpubbise@codeaurora.org>
3 Date: Wed, 21 Nov 2018 16:33:48 +0530
4 Subject: [PATCH] {nl,mac}80211: allow 4addr AP operation on crypto controlled
5  devices
6
7 As per the current design, for sw crypto controlled devices, it is
8 the device which has to advertise the support for AP/VLAN iftype
9 based on it's capability to tranmsit packets encrypted in software
10 (In VLAN functionality, group traffic generated for a specific
11 VLAN group is always encrypted in software). Commit db3bdcb9c3ff
12 ("mac80211: allow AP_VLAN operation on crypto controlled devices")
13 has introduced this change.
14
15 Since 4addr AP operation also uses AP/VLAN iftype, this conditional
16 way of advertising AP/VLAN support has broken 4addr AP mode operation on
17 crypto controlled devices which do not support VLAN functionality.
18
19 For example:
20 In the case of ath10k driver, not all firmwares have support for VLAN
21 functionality but all can support 4addr AP operation. Because AP/VLAN
22 support is not advertised for these devices, 4addr AP operations are
23 also blocked.
24
25 Fix this by allowing 4addr opertion on devices which do not advertise
26 AP/VLAN iftype but which can support 4addr operation (the desicion is
27 taken based on the wiphy flag WIPHY_FLAG_4ADDR_AP).
28
29 Fixes: Commit db3bdcb9c3ff ("mac80211: allow AP_VLAN operation on
30 crypto controlled devices")
31 Signed-off-by: Manikanta Pubbisetty <mpubbise@codeaurora.org>
32 ---
33  include/net/cfg80211.h |  3 ++-
34  net/mac80211/util.c    |  4 +++-
35  net/wireless/core.c    |  9 +++++++--
36  net/wireless/nl80211.c | 10 ++++++++--
37  4 files changed, 20 insertions(+), 6 deletions(-)
38
39 --- a/include/net/cfg80211.h
40 +++ b/include/net/cfg80211.h
41 @@ -3457,7 +3457,8 @@ struct cfg80211_ops {
42   *     on wiphy_new(), but can be changed by the driver if it has a good
43   *     reason to override the default
44   * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station
45 - *     on a VLAN interface)
46 + *     on a VLAN interface). This flag also serves an extra purpose of
47 + *     supporting 4ADDR AP mode on devices which do not support AP/VLAN iftype.
48   * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station
49   * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the
50   *     control port protocol ethertype. The device also honours the
51 --- a/net/mac80211/util.c
52 +++ b/net/mac80211/util.c
53 @@ -3622,7 +3622,9 @@ int ieee80211_check_combinations(struct
54         }
55  
56         /* Always allow software iftypes */
57 -       if (local->hw.wiphy->software_iftypes & BIT(iftype)) {
58 +       if (local->hw.wiphy->software_iftypes & BIT(iftype) ||
59 +           (iftype == NL80211_IFTYPE_AP_VLAN &&
60 +            local->hw.wiphy->flags & WIPHY_FLAG_4ADDR_AP)) {
61                 if (radar_detect)
62                         return -EINVAL;
63                 return 0;
64 --- a/net/wireless/core.c
65 +++ b/net/wireless/core.c
66 @@ -1351,8 +1351,13 @@ static int cfg80211_netdev_notifier_call
67                 }
68                 break;
69         case NETDEV_PRE_UP:
70 -               if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
71 -                       return notifier_from_errno(-EOPNOTSUPP);
72 +               if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) {
73 +                       if (!(wdev->iftype == NL80211_IFTYPE_AP_VLAN &&
74 +                             rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP &&
75 +                             wdev->use_4addr))
76 +                               return notifier_from_errno(-EOPNOTSUPP);
77 +               }
78 +
79                 if (rfkill_blocked(rdev->rfkill))
80                         return notifier_from_errno(-ERFKILL);
81                 break;
82 --- a/net/wireless/nl80211.c
83 +++ b/net/wireless/nl80211.c
84 @@ -3194,8 +3194,7 @@ static int nl80211_new_interface(struct
85                         return -EINVAL;
86         }
87  
88 -       if (!rdev->ops->add_virtual_intf ||
89 -           !(rdev->wiphy.interface_modes & (1 << type)))
90 +       if (!rdev->ops->add_virtual_intf)
91                 return -EOPNOTSUPP;
92  
93         if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
94 @@ -3214,6 +3213,13 @@ static int nl80211_new_interface(struct
95                         return err;
96         }
97  
98 +       if (!(rdev->wiphy.interface_modes & (1 << type))) {
99 +               if (!(type == NL80211_IFTYPE_AP_VLAN &&
100 +                     rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP &&
101 +                     params.use_4addr))
102 +                       return -EOPNOTSUPP;
103 +       }
104 +
105         err = nl80211_parse_mon_options(rdev, type, info, &params);
106         if (err < 0)
107                 return err;