d0551c509f7ef42a07911680a9e6257429265e88
[librecmc/librecmc.git] /
1 From 0ff57171d6d225558c81a69439d5323e35b40549 Mon Sep 17 00:00:00 2001
2 From: Vinayak Yadawad <vinayak.yadawad@broadcom.com>
3 Date: Wed, 7 Sep 2022 18:14:48 +0530
4 Subject: [PATCH] cfg80211: Update Transition Disable policy during port
5  authorization
6
7 In case of 4way handshake offload, transition disable policy
8 updated by the AP during EAPOL 3/4 is not updated to the upper layer.
9 This results in mismatch between transition disable policy
10 between the upper layer and the driver. This patch addresses this
11 issue by updating transition disable policy as part of port
12 authorization indication.
13
14 Signed-off-by: Vinayak Yadawad <vinayak.yadawad@broadcom.com>
15 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
16 ---
17  .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c  |  2 +-
18  include/net/cfg80211.h                               |  4 +++-
19  include/uapi/linux/nl80211.h                         |  3 +++
20  net/wireless/core.h                                  |  5 ++++-
21  net/wireless/nl80211.c                               |  8 +++++++-
22  net/wireless/nl80211.h                               |  3 ++-
23  net/wireless/sme.c                                   | 12 ++++++++----
24  net/wireless/util.c                                  |  4 +++-
25  8 files changed, 31 insertions(+), 10 deletions(-)
26
27 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
28 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
29 @@ -6005,7 +6005,7 @@ done:
30         brcmf_dbg(CONN, "Report roaming result\n");
31  
32         if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) {
33 -               cfg80211_port_authorized(ndev, profile->bssid, GFP_KERNEL);
34 +               cfg80211_port_authorized(ndev, profile->bssid, NULL, 0, GFP_KERNEL);
35                 brcmf_dbg(CONN, "Report port authorized\n");
36         }
37  
38 --- a/include/net/cfg80211.h
39 +++ b/include/net/cfg80211.h
40 @@ -7720,6 +7720,8 @@ void cfg80211_roamed(struct net_device *
41   *
42   * @dev: network device
43   * @bssid: the BSSID of the AP
44 + * @td_bitmap: transition disable policy
45 + * @td_bitmap_len: Length of transition disable policy
46   * @gfp: allocation flags
47   *
48   * This function should be called by a driver that supports 4 way handshake
49 @@ -7730,7 +7732,7 @@ void cfg80211_roamed(struct net_device *
50   * indicate the 802.11 association.
51   */
52  void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
53 -                             gfp_t gfp);
54 +                             const u8* td_bitmap, u8 td_bitmap_len, gfp_t gfp);
55  
56  /**
57   * cfg80211_disconnected - notify cfg80211 that connection was dropped
58 --- a/include/uapi/linux/nl80211.h
59 +++ b/include/uapi/linux/nl80211.h
60 @@ -2749,6 +2749,8 @@ enum nl80211_commands {
61   *     When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX
62   *     timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates
63   *     the incoming frame RX timestamp.
64 + * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent
65 + *     (re)associations.
66   * @NUM_NL80211_ATTR: total number of nl80211_attrs available
67   * @NL80211_ATTR_MAX: highest attribute number currently defined
68   * @__NL80211_ATTR_AFTER_LAST: internal use
69 @@ -3276,6 +3278,7 @@ enum nl80211_attrs {
70  
71         NL80211_ATTR_TX_HW_TIMESTAMP,
72         NL80211_ATTR_RX_HW_TIMESTAMP,
73 +       NL80211_ATTR_TD_BITMAP,
74  
75         /* add attributes here, update the policy in nl80211.c */
76  
77 --- a/net/wireless/core.h
78 +++ b/net/wireless/core.h
79 @@ -271,6 +271,8 @@ struct cfg80211_event {
80                 } ij;
81                 struct {
82                         u8 bssid[ETH_ALEN];
83 +                       const u8 *td_bitmap;
84 +                       u8 td_bitmap_len;
85                 } pa;
86         };
87  };
88 @@ -409,7 +411,8 @@ int cfg80211_disconnect(struct cfg80211_
89                         bool wextev);
90  void __cfg80211_roamed(struct wireless_dev *wdev,
91                        struct cfg80211_roam_info *info);
92 -void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid);
93 +void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid,
94 +                               const u8 *td_bitmap, u8 td_bitmap_len);
95  int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
96                               struct wireless_dev *wdev);
97  void cfg80211_autodisconnect_wk(struct work_struct *work);
98 --- a/net/wireless/nl80211.c
99 +++ b/net/wireless/nl80211.c
100 @@ -17936,7 +17936,8 @@ void nl80211_send_roamed(struct cfg80211
101  }
102  
103  void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
104 -                                 struct net_device *netdev, const u8 *bssid)
105 +                                 struct net_device *netdev, const u8 *bssid,
106 +                                 const u8 *td_bitmap, u8 td_bitmap_len)
107  {
108         struct sk_buff *msg;
109         void *hdr;
110 @@ -17956,6 +17957,11 @@ void nl80211_send_port_authorized(struct
111             nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
112                 goto nla_put_failure;
113  
114 +       if ((td_bitmap_len > 0) && td_bitmap)
115 +               if (nla_put(msg, NL80211_ATTR_TD_BITMAP,
116 +                           td_bitmap_len, td_bitmap))
117 +                       goto nla_put_failure;
118 +
119         genlmsg_end(msg, hdr);
120  
121         genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
122 --- a/net/wireless/nl80211.h
123 +++ b/net/wireless/nl80211.h
124 @@ -83,7 +83,8 @@ void nl80211_send_roamed(struct cfg80211
125                          struct net_device *netdev,
126                          struct cfg80211_roam_info *info, gfp_t gfp);
127  void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
128 -                                 struct net_device *netdev, const u8 *bssid);
129 +                                 struct net_device *netdev, const u8 *bssid,
130 +                                 const u8 *td_bitmap, u8 td_bitmap_len);
131  void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
132                                struct net_device *netdev, u16 reason,
133                                const u8 *ie, size_t ie_len, bool from_ap);
134 --- a/net/wireless/sme.c
135 +++ b/net/wireless/sme.c
136 @@ -1266,7 +1266,8 @@ out:
137  }
138  EXPORT_SYMBOL(cfg80211_roamed);
139  
140 -void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid)
141 +void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid,
142 +                                       const u8 *td_bitmap, u8 td_bitmap_len)
143  {
144         ASSERT_WDEV_LOCK(wdev);
145  
146 @@ -1279,11 +1280,11 @@ void __cfg80211_port_authorized(struct w
147                 return;
148  
149         nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev,
150 -                                    bssid);
151 +                                    bssid, td_bitmap, td_bitmap_len);
152  }
153  
154  void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
155 -                             gfp_t gfp)
156 +                             const u8 *td_bitmap, u8 td_bitmap_len, gfp_t gfp)
157  {
158         struct wireless_dev *wdev = dev->ieee80211_ptr;
159         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
160 @@ -1293,12 +1294,15 @@ void cfg80211_port_authorized(struct net
161         if (WARN_ON(!bssid))
162                 return;
163  
164 -       ev = kzalloc(sizeof(*ev), gfp);
165 +       ev = kzalloc(sizeof(*ev) + td_bitmap_len, gfp);
166         if (!ev)
167                 return;
168  
169         ev->type = EVENT_PORT_AUTHORIZED;
170         memcpy(ev->pa.bssid, bssid, ETH_ALEN);
171 +       ev->pa.td_bitmap = ((u8 *)ev) + sizeof(*ev);
172 +       ev->pa.td_bitmap_len = td_bitmap_len;
173 +       memcpy((void *)ev->pa.td_bitmap, td_bitmap, td_bitmap_len);
174  
175         /*
176          * Use the wdev event list so that if there are pending
177 --- a/net/wireless/util.c
178 +++ b/net/wireless/util.c
179 @@ -1057,7 +1057,9 @@ void cfg80211_process_wdev_events(struct
180                         __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);
181                         break;
182                 case EVENT_PORT_AUTHORIZED:
183 -                       __cfg80211_port_authorized(wdev, ev->pa.bssid);
184 +                       __cfg80211_port_authorized(wdev, ev->pa.bssid,
185 +                                                  ev->pa.td_bitmap,
186 +                                                  ev->pa.td_bitmap_len);
187                         break;
188                 }
189                 wdev_unlock(wdev);