OSDN Git Service

wifi: cfg80211: extend cfg80211_rx_assoc_resp() for MLO
authorJohannes Berg <johannes.berg@intel.com>
Tue, 28 Jun 2022 15:17:05 +0000 (17:17 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 15 Jul 2022 09:43:17 +0000 (11:43 +0200)
Extend the cfg80211_rx_assoc_resp() to cover multiple
BSSes, the AP MLD address and local link addresses
for MLO.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
net/mac80211/mlme.c
net/wireless/mlme.c
net/wireless/trace.h

index 2628e8f..2fe3eff 100644 (file)
@@ -6886,14 +6886,21 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr);
  *     as the AC bitmap in the QoS info field
  * @req_ies: information elements from the (Re)Association Request frame
  * @req_ies_len: length of req_ies data
+ * @ap_mld_addr: AP MLD address (in case of MLO)
+ * @links: per-link information indexed by link ID, use links[0] for
+ *     non-MLO connections
  */
 struct cfg80211_rx_assoc_resp {
-       struct cfg80211_bss *bss;
        const u8 *buf;
        size_t len;
        const u8 *req_ies;
        size_t req_ies_len;
        int uapsd_queues;
+       const u8 *ap_mld_addr;
+       struct {
+               const u8 *addr;
+               struct cfg80211_bss *bss;
+       } links[IEEE80211_MLD_MAX_NUM_LINKS];
 };
 
 /**
index ecbd70a..29c1fe8 100644 (file)
@@ -3995,7 +3995,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                info.success = 1;
        }
 
-       resp.bss = cbss;
+       resp.links[0].bss = cbss;
        resp.buf = (u8 *)mgmt;
        resp.len = len;
        resp.req_ies = ifmgd->assoc_req_ies;
index a6ad696..80f11a2 100644 (file)
@@ -28,28 +28,41 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
        struct wiphy *wiphy = wdev->wiphy;
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)data->buf;
-       struct cfg80211_connect_resp_params cr;
-       const u8 *resp_ie = mgmt->u.assoc_resp.variable;
-       size_t resp_ie_len = data->len - offsetof(struct ieee80211_mgmt,
-                                                 u.assoc_resp.variable);
-
-       if (data->bss->channel->band == NL80211_BAND_S1GHZ) {
-               resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable;
-               resp_ie_len = data->len - offsetof(struct ieee80211_mgmt,
-                                                  u.s1g_assoc_resp.variable);
-       }
+       struct cfg80211_connect_resp_params cr = {
+               .timeout_reason = NL80211_TIMEOUT_UNSPECIFIED,
+               .req_ie = data->req_ies,
+               .req_ie_len = data->req_ies_len,
+               .resp_ie = mgmt->u.assoc_resp.variable,
+               .resp_ie_len = data->len -
+                              offsetof(struct ieee80211_mgmt,
+                                       u.assoc_resp.variable),
+               .status = le16_to_cpu(mgmt->u.assoc_resp.status_code),
+               .ap_mld_addr = data->ap_mld_addr,
+       };
+       unsigned int link_id;
+
+       for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) {
+               cr.links[link_id].bss = data->links[link_id].bss;
+               if (!cr.links[link_id].bss)
+                       continue;
+               cr.links[link_id].bssid = data->links[link_id].bss->bssid;
+               cr.links[link_id].addr = data->links[link_id].addr;
+               /* need to have local link addresses for MLO connections */
+               WARN_ON(cr.ap_mld_addr && !cr.links[link_id].addr);
+
+               if (cr.links[link_id].bss->channel->band == NL80211_BAND_S1GHZ) {
+                       WARN_ON(link_id);
+                       cr.resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable;
+                       cr.resp_ie_len = data->len -
+                                        offsetof(struct ieee80211_mgmt,
+                                                 u.s1g_assoc_resp.variable);
+               }
 
-       memset(&cr, 0, sizeof(cr));
-       cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code);
-       cr.links[0].bssid = mgmt->bssid;
-       cr.links[0].bss = data->bss;
-       cr.req_ie = data->req_ies;
-       cr.req_ie_len = data->req_ies_len;
-       cr.resp_ie = resp_ie;
-       cr.resp_ie_len = resp_ie_len;
-       cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
+               if (cr.ap_mld_addr)
+                       cr.valid_links |= BIT(link_id);
+       }
 
-       trace_cfg80211_send_rx_assoc(dev, data->bss);
+       trace_cfg80211_send_rx_assoc(dev, data);
 
        /*
         * This is a bit of a hack, we don't notify userspace of
@@ -58,8 +71,15 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
         * frame instead of reassoc.
         */
        if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) {
-               cfg80211_unhold_bss(bss_from_pub(data->bss));
-               cfg80211_put_bss(wiphy, data->bss);
+               for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) {
+                       struct cfg80211_bss *bss = data->links[link_id].bss;
+
+                       if (!bss)
+                               continue;
+
+                       cfg80211_unhold_bss(bss_from_pub(bss));
+                       cfg80211_put_bss(wiphy, bss);
+               }
                return;
        }
 
index 94d107c..dac66ad 100644 (file)
@@ -2887,20 +2887,20 @@ DEFINE_EVENT(netdev_evt_only, cfg80211_send_rx_auth,
 );
 
 TRACE_EVENT(cfg80211_send_rx_assoc,
-       TP_PROTO(struct net_device *netdev, struct cfg80211_bss *bss),
-       TP_ARGS(netdev, bss),
+       TP_PROTO(struct net_device *netdev,
+                struct cfg80211_rx_assoc_resp *data),
+       TP_ARGS(netdev, data),
        TP_STRUCT__entry(
                NETDEV_ENTRY
-               MAC_ENTRY(bssid)
-               CHAN_ENTRY
+               MAC_ENTRY(ap_addr)
        ),
        TP_fast_assign(
                NETDEV_ASSIGN;
-               MAC_ASSIGN(bssid, bss->bssid);
-               CHAN_ASSIGN(bss->channel);
+               MAC_ASSIGN(ap_addr,
+                          data->ap_mld_addr ?: data->links[0].bss->bssid);
        ),
-       TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", " CHAN_PR_FMT,
-                 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
+       TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT,
+                 NETDEV_PR_ARG, MAC_PR_ARG(ap_addr))
 );
 
 DECLARE_EVENT_CLASS(netdev_frame_event,