developer | ebaa551 | 2023-04-19 18:23:21 +0800 | [diff] [blame] | 1 | From e0756f54dea42f1833e40ddfb0deb5d0b8e6dda4 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 3/9] 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 | diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |
| 28 | index ea8409e..bddc0af 100644 |
| 29 | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |
| 30 | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |
| 31 | @@ -6005,7 +6005,7 @@ done: |
| 32 | brcmf_dbg(CONN, "Report roaming result\n"); |
| 33 | |
| 34 | if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) { |
| 35 | - cfg80211_port_authorized(ndev, profile->bssid, GFP_KERNEL); |
| 36 | + cfg80211_port_authorized(ndev, profile->bssid, NULL, 0, GFP_KERNEL); |
| 37 | brcmf_dbg(CONN, "Report port authorized\n"); |
| 38 | } |
| 39 | |
| 40 | diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h |
| 41 | index 803949b..9420086 100644 |
| 42 | --- a/include/net/cfg80211.h |
| 43 | +++ b/include/net/cfg80211.h |
| 44 | @@ -7717,6 +7717,8 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, |
| 45 | * |
| 46 | * @dev: network device |
| 47 | * @bssid: the BSSID of the AP |
| 48 | + * @td_bitmap: transition disable policy |
| 49 | + * @td_bitmap_len: Length of transition disable policy |
| 50 | * @gfp: allocation flags |
| 51 | * |
| 52 | * This function should be called by a driver that supports 4 way handshake |
| 53 | @@ -7727,7 +7729,7 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, |
| 54 | * indicate the 802.11 association. |
| 55 | */ |
| 56 | void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid, |
| 57 | - gfp_t gfp); |
| 58 | + const u8* td_bitmap, u8 td_bitmap_len, gfp_t gfp); |
| 59 | |
| 60 | /** |
| 61 | * cfg80211_disconnected - notify cfg80211 that connection was dropped |
| 62 | diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h |
| 63 | index c32e761..c14a91b 100644 |
| 64 | --- a/include/uapi/linux/nl80211.h |
| 65 | +++ b/include/uapi/linux/nl80211.h |
| 66 | @@ -2749,6 +2749,8 @@ enum nl80211_commands { |
| 67 | * When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX |
| 68 | * timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates |
| 69 | * the incoming frame RX timestamp. |
| 70 | + * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent |
| 71 | + * (re)associations. |
| 72 | * @NUM_NL80211_ATTR: total number of nl80211_attrs available |
| 73 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
| 74 | * @__NL80211_ATTR_AFTER_LAST: internal use |
| 75 | @@ -3276,6 +3278,7 @@ enum nl80211_attrs { |
| 76 | |
| 77 | NL80211_ATTR_TX_HW_TIMESTAMP, |
| 78 | NL80211_ATTR_RX_HW_TIMESTAMP, |
| 79 | + NL80211_ATTR_TD_BITMAP, |
| 80 | |
| 81 | /* add attributes here, update the policy in nl80211.c */ |
| 82 | |
| 83 | diff --git a/net/wireless/core.h b/net/wireless/core.h |
| 84 | index f4d3b83..382455c 100644 |
| 85 | --- a/net/wireless/core.h |
| 86 | +++ b/net/wireless/core.h |
| 87 | @@ -271,6 +271,8 @@ struct cfg80211_event { |
| 88 | } ij; |
| 89 | struct { |
| 90 | u8 bssid[ETH_ALEN]; |
| 91 | + const u8 *td_bitmap; |
| 92 | + u8 td_bitmap_len; |
| 93 | } pa; |
| 94 | }; |
| 95 | }; |
| 96 | @@ -409,7 +411,8 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev, |
| 97 | bool wextev); |
| 98 | void __cfg80211_roamed(struct wireless_dev *wdev, |
| 99 | struct cfg80211_roam_info *info); |
| 100 | -void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid); |
| 101 | +void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid, |
| 102 | + const u8 *td_bitmap, u8 td_bitmap_len); |
| 103 | int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, |
| 104 | struct wireless_dev *wdev); |
| 105 | void cfg80211_autodisconnect_wk(struct work_struct *work); |
| 106 | diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c |
| 107 | index 777c141..6a97e52 100644 |
| 108 | --- a/net/wireless/nl80211.c |
| 109 | +++ b/net/wireless/nl80211.c |
| 110 | @@ -17936,7 +17936,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, |
| 111 | } |
| 112 | |
| 113 | void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev, |
| 114 | - struct net_device *netdev, const u8 *bssid) |
| 115 | + struct net_device *netdev, const u8 *bssid, |
| 116 | + const u8 *td_bitmap, u8 td_bitmap_len) |
| 117 | { |
| 118 | struct sk_buff *msg; |
| 119 | void *hdr; |
| 120 | @@ -17956,6 +17957,11 @@ void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev, |
| 121 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) |
| 122 | goto nla_put_failure; |
| 123 | |
| 124 | + if ((td_bitmap_len > 0) && td_bitmap) |
| 125 | + if (nla_put(msg, NL80211_ATTR_TD_BITMAP, |
| 126 | + td_bitmap_len, td_bitmap)) |
| 127 | + goto nla_put_failure; |
| 128 | + |
| 129 | genlmsg_end(msg, hdr); |
| 130 | |
| 131 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 132 | diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h |
| 133 | index 855d540..ba9457e 100644 |
| 134 | --- a/net/wireless/nl80211.h |
| 135 | +++ b/net/wireless/nl80211.h |
| 136 | @@ -83,7 +83,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, |
| 137 | struct net_device *netdev, |
| 138 | struct cfg80211_roam_info *info, gfp_t gfp); |
| 139 | void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev, |
| 140 | - struct net_device *netdev, const u8 *bssid); |
| 141 | + struct net_device *netdev, const u8 *bssid, |
| 142 | + const u8 *td_bitmap, u8 td_bitmap_len); |
| 143 | void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, |
| 144 | struct net_device *netdev, u16 reason, |
| 145 | const u8 *ie, size_t ie_len, bool from_ap); |
| 146 | diff --git a/net/wireless/sme.c b/net/wireless/sme.c |
| 147 | index 05e4f29..1ee4408 100644 |
| 148 | --- a/net/wireless/sme.c |
| 149 | +++ b/net/wireless/sme.c |
| 150 | @@ -1266,7 +1266,8 @@ out: |
| 151 | } |
| 152 | EXPORT_SYMBOL(cfg80211_roamed); |
| 153 | |
| 154 | -void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid) |
| 155 | +void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid, |
| 156 | + const u8 *td_bitmap, u8 td_bitmap_len) |
| 157 | { |
| 158 | ASSERT_WDEV_LOCK(wdev); |
| 159 | |
| 160 | @@ -1279,11 +1280,11 @@ void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid) |
| 161 | return; |
| 162 | |
| 163 | nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev, |
| 164 | - bssid); |
| 165 | + bssid, td_bitmap, td_bitmap_len); |
| 166 | } |
| 167 | |
| 168 | void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid, |
| 169 | - gfp_t gfp) |
| 170 | + const u8 *td_bitmap, u8 td_bitmap_len, gfp_t gfp) |
| 171 | { |
| 172 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
| 173 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
| 174 | @@ -1293,12 +1294,15 @@ void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid, |
| 175 | if (WARN_ON(!bssid)) |
| 176 | return; |
| 177 | |
| 178 | - ev = kzalloc(sizeof(*ev), gfp); |
| 179 | + ev = kzalloc(sizeof(*ev) + td_bitmap_len, gfp); |
| 180 | if (!ev) |
| 181 | return; |
| 182 | |
| 183 | ev->type = EVENT_PORT_AUTHORIZED; |
| 184 | memcpy(ev->pa.bssid, bssid, ETH_ALEN); |
| 185 | + ev->pa.td_bitmap = ((u8 *)ev) + sizeof(*ev); |
| 186 | + ev->pa.td_bitmap_len = td_bitmap_len; |
| 187 | + memcpy((void *)ev->pa.td_bitmap, td_bitmap, td_bitmap_len); |
| 188 | |
| 189 | /* |
| 190 | * Use the wdev event list so that if there are pending |
| 191 | diff --git a/net/wireless/util.c b/net/wireless/util.c |
| 192 | index 769f8fe..fdc140e 100644 |
| 193 | --- a/net/wireless/util.c |
| 194 | +++ b/net/wireless/util.c |
| 195 | @@ -1057,7 +1057,9 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) |
| 196 | __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev); |
| 197 | break; |
| 198 | case EVENT_PORT_AUTHORIZED: |
| 199 | - __cfg80211_port_authorized(wdev, ev->pa.bssid); |
| 200 | + __cfg80211_port_authorized(wdev, ev->pa.bssid, |
| 201 | + ev->pa.td_bitmap, |
| 202 | + ev->pa.td_bitmap_len); |
| 203 | break; |
| 204 | } |
| 205 | wdev_unlock(wdev); |
| 206 | -- |
| 207 | 2.39.2 |
| 208 | |