cfg80211: Update Transition Disable policy during port authorization
authorVinayak Yadawad <vinayak.yadawad@broadcom.com>
Wed, 7 Sep 2022 12:44:48 +0000 (18:14 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 7 Oct 2022 13:27:40 +0000 (15:27 +0200)
In case of 4way handshake offload, transition disable policy
updated by the AP during EAPOL 3/4 is not updated to the upper layer.
This results in mismatch between transition disable policy
between the upper layer and the driver. This patch addresses this
issue by updating transition disable policy as part of port
authorization indication.

Signed-off-by: Vinayak Yadawad <vinayak.yadawad@broadcom.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/core.h
net/wireless/nl80211.c
net/wireless/nl80211.h
net/wireless/sme.c
net/wireless/util.c

index bf184c0e64cb13d906e7b28c35a2b9a889cd8773..3f2336062217cd890baf1b249b9a1e17c447f341 100644 (file)
@@ -6268,7 +6268,7 @@ done:
        brcmf_dbg(CONN, "Report roaming result\n");
 
        if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) {
-               cfg80211_port_authorized(ndev, profile->bssid, GFP_KERNEL);
+               cfg80211_port_authorized(ndev, profile->bssid, NULL, 0, GFP_KERNEL);
                brcmf_dbg(CONN, "Report port authorized\n");
        }
 
index 659dd1bee70fa1fcd6d1bae57f22451bc7cd30d6..11a370e64143b4337afa512394ecf2da476281d1 100644 (file)
@@ -7683,6 +7683,8 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
  *
  * @dev: network device
  * @bssid: the BSSID of the AP
+ * @td_bitmap: transition disable policy
+ * @td_bitmap_len: Length of transition disable policy
  * @gfp: allocation flags
  *
  * This function should be called by a driver that supports 4 way handshake
@@ -7693,7 +7695,7 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
  * indicate the 802.11 association.
  */
 void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
-                             gfp_t gfp);
+                             const u8* td_bitmap, u8 td_bitmap_len, gfp_t gfp);
 
 /**
  * cfg80211_disconnected - notify cfg80211 that connection was dropped
index c32e7616a366a04695511679ca9e8e0332662513..c14a91bbca7c9e6000978174becfa3e52982d1d2 100644 (file)
@@ -2749,6 +2749,8 @@ enum nl80211_commands {
  *     When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX
  *     timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates
  *     the incoming frame RX timestamp.
+ * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent
+ *     (re)associations.
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3276,6 +3278,7 @@ enum nl80211_attrs {
 
        NL80211_ATTR_TX_HW_TIMESTAMP,
        NL80211_ATTR_RX_HW_TIMESTAMP,
+       NL80211_ATTR_TD_BITMAP,
 
        /* add attributes here, update the policy in nl80211.c */
 
index 775e16cb99edab3f1fd979da3964c492733258cd..af85d8909935e28128af1424080e8efd21c74fdb 100644 (file)
@@ -271,6 +271,8 @@ struct cfg80211_event {
                } ij;
                struct {
                        u8 bssid[ETH_ALEN];
+                       const u8 *td_bitmap;
+                       u8 td_bitmap_len;
                } pa;
        };
 };
@@ -409,7 +411,8 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
                        bool wextev);
 void __cfg80211_roamed(struct wireless_dev *wdev,
                       struct cfg80211_roam_info *info);
-void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid);
+void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid,
+                               const u8 *td_bitmap, u8 td_bitmap_len);
 int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
                              struct wireless_dev *wdev);
 void cfg80211_autodisconnect_wk(struct work_struct *work);
index 1d0277758d0ef680aa429ba41a684ede39c4e5cc..fe368af39554dd2c0f07939dc773821bbb3c3bfa 100644 (file)
@@ -17942,7 +17942,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
 }
 
 void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
-                                 struct net_device *netdev, const u8 *bssid)
+                                 struct net_device *netdev, const u8 *bssid,
+                                 const u8 *td_bitmap, u8 td_bitmap_len)
 {
        struct sk_buff *msg;
        void *hdr;
@@ -17962,6 +17963,11 @@ void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
            nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
                goto nla_put_failure;
 
+       if ((td_bitmap_len > 0) && td_bitmap)
+               if (nla_put(msg, NL80211_ATTR_TD_BITMAP,
+                           td_bitmap_len, td_bitmap))
+                       goto nla_put_failure;
+
        genlmsg_end(msg, hdr);
 
        genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
index 855d540ddfb97b2580be3057505b7d3c1108e177..ba9457e94c43ccda5c387590d7b61b8f0f9a964d 100644 (file)
@@ -83,7 +83,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
                         struct net_device *netdev,
                         struct cfg80211_roam_info *info, gfp_t gfp);
 void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
-                                 struct net_device *netdev, const u8 *bssid);
+                                 struct net_device *netdev, const u8 *bssid,
+                                 const u8 *td_bitmap, u8 td_bitmap_len);
 void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
                               struct net_device *netdev, u16 reason,
                               const u8 *ie, size_t ie_len, bool from_ap);
index f94497e9db431eea9c89d0638ccd11bd2da5284c..4b5b6ee0fe013e922dfe6a5ce11c0c0f8dc38f30 100644 (file)
@@ -1251,7 +1251,8 @@ out:
 }
 EXPORT_SYMBOL(cfg80211_roamed);
 
-void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid)
+void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid,
+                                       const u8 *td_bitmap, u8 td_bitmap_len)
 {
        ASSERT_WDEV_LOCK(wdev);
 
@@ -1264,11 +1265,11 @@ void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid)
                return;
 
        nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev,
-                                    bssid);
+                                    bssid, td_bitmap, td_bitmap_len);
 }
 
 void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
-                             gfp_t gfp)
+                             const u8 *td_bitmap, u8 td_bitmap_len, gfp_t gfp)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
@@ -1278,12 +1279,15 @@ void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
        if (WARN_ON(!bssid))
                return;
 
-       ev = kzalloc(sizeof(*ev), gfp);
+       ev = kzalloc(sizeof(*ev) + td_bitmap_len, gfp);
        if (!ev)
                return;
 
        ev->type = EVENT_PORT_AUTHORIZED;
        memcpy(ev->pa.bssid, bssid, ETH_ALEN);
+       ev->pa.td_bitmap = ((u8 *)ev) + sizeof(*ev);
+       ev->pa.td_bitmap_len = td_bitmap_len;
+       memcpy((void *)ev->pa.td_bitmap, td_bitmap, td_bitmap_len);
 
        /*
         * Use the wdev event list so that if there are pending
index 01493568a21dfe07d36377c2e4a1ca7c602ac037..f09d528e51991bd390e8e3bfdd7828e597c70680 100644 (file)
@@ -988,7 +988,9 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
                        __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);
                        break;
                case EVENT_PORT_AUTHORIZED:
-                       __cfg80211_port_authorized(wdev, ev->pa.bssid);
+                       __cfg80211_port_authorized(wdev, ev->pa.bssid,
+                                                  ev->pa.td_bitmap,
+                                                  ev->pa.td_bitmap_len);
                        break;
                }
                wdev_unlock(wdev);