]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Support MLD association request
authorIlan Peer <ilan.peer@intel.com>
Wed, 30 Nov 2022 13:09:29 +0000 (15:09 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 3 Dec 2022 15:19:00 +0000 (17:19 +0200)
Define additional association parameters for MLD to be able to indicate
information for all the requested links and fill these into nl80211
attributes.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
src/drivers/driver.h
src/drivers/driver_nl80211.c

index 78d229c2453ccab6f9e8ab6166a0c15b8c271d20..9825b1a4496db732560e418b483bd1a08373ceac 100644 (file)
@@ -898,6 +898,38 @@ struct wpa_driver_sta_auth_params {
        size_t fils_kek_len;
 };
 
+struct wpa_driver_mld_params {
+       /**
+        * mld_addr - AP's MLD address
+        */
+       const u8 *mld_addr;
+
+       /**
+        * valid_links - The valid links including the association link
+        */
+       u16 valid_links;
+
+       /**
+        * assoc_link_id - The link on which the association is performed
+        */
+       u8 assoc_link_id;
+
+       /**
+        * mld_links - Link information
+        *
+        * Should include information on all the requested links for association
+        * including the link on which the association should take place.
+        * For the association link, the ies and ies_len should be NULL and
+        * 0 respectively.
+        */
+       struct {
+               int freq;
+               const u8 *bssid;
+               const u8 *ies;
+               size_t ies_len;
+       } mld_links[MAX_NUM_MLD_LINKS];
+};
+
 /**
  * struct wpa_driver_associate_params - Association parameters
  * Data for struct wpa_driver_ops::associate().
@@ -1271,6 +1303,11 @@ struct wpa_driver_associate_params {
         * disable_eht - Disable EHT for this connection
         */
        int disable_eht;
+
+       /*
+        * mld_params - MLD association parameters
+        */
+       struct wpa_driver_mld_params mld_params;
 };
 
 enum hide_ssid {
index 4796ed227a1b0efea53fa4c9fc0d0470b8001c67..a2cc6ec4767a906fe507c43ae5ce7a775dce536f 100644 (file)
@@ -6242,10 +6242,85 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
                                  struct wpa_driver_associate_params *params,
                                  struct nl_msg *msg)
 {
+       if (params->mld_params.mld_addr && params->mld_params.valid_links > 0) {
+               struct wpa_driver_mld_params *mld_params = &params->mld_params;
+               struct nlattr *links, *attr;
+               int i;
+               u8 link_id;
+
+               wpa_printf(MSG_DEBUG, "  * MLD: MLD addr=" MACSTR,
+                          MAC2STR(mld_params->mld_addr));
+
+               if (nla_put(msg, NL80211_ATTR_MLD_ADDR, ETH_ALEN,
+                           mld_params->mld_addr) ||
+                   nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID,
+                              mld_params->assoc_link_id))
+                       return -1;
+
+               links = nla_nest_start(msg, NL80211_ATTR_MLO_LINKS);
+               if (!links)
+                       return -1;
+
+               attr = nla_nest_start(msg, 0);
+               if (!attr)
+                       return -1;
+
+               /* First add the association link ID */
+               link_id = mld_params->assoc_link_id;
+               if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id) ||
+                   nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
+                           mld_params->mld_links[link_id].bssid) ||
+                   nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
+                               mld_params->mld_links[link_id].freq))
+                       return -1;
+
+               os_memcpy(drv->sta_mlo_info.links[link_id].bssid,
+                         mld_params->mld_links[link_id].bssid, ETH_ALEN);
+
+               nla_nest_end(msg, attr);
+
+               for (i = 1, link_id = 0; link_id < MAX_NUM_MLD_LINKS;
+                    link_id++) {
+                       if (!(mld_params->valid_links & BIT(link_id)) ||
+                           link_id == mld_params->assoc_link_id)
+                               continue;
+
+                       attr = nla_nest_start(msg, i);
+                       if (!attr)
+                               return -1;
+
+                       if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID,
+                                      link_id) ||
+                           nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
+                                   mld_params->mld_links[link_id].bssid) ||
+                           nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
+                                       mld_params->mld_links[link_id].freq) ||
+                           (mld_params->mld_links[link_id].ies &&
+                            mld_params->mld_links[i].ies_len &&
+                            nla_put(msg, NL80211_ATTR_IE,
+                                    mld_params->mld_links[link_id].ies_len,
+                                    mld_params->mld_links[link_id].ies)))
+                               return -1;
+
+                       os_memcpy(drv->sta_mlo_info.links[link_id].bssid,
+                                 mld_params->mld_links[link_id].bssid,
+                                 ETH_ALEN);
+                       nla_nest_end(msg, attr);
+                       i++;
+               }
+
+               nla_nest_end(msg, links);
+
+               os_memcpy(drv->sta_mlo_info.ap_mld_addr,
+                         params->mld_params.mld_addr, ETH_ALEN);
+               drv->sta_mlo_info.assoc_link_id = mld_params->assoc_link_id;
+               drv->sta_mlo_info.req_links = mld_params->valid_links;
+       }
+
        if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
                return -1;
 
-       if (params->bssid) {
+       if (params->bssid && !params->mld_params.mld_addr) {
                wpa_printf(MSG_DEBUG, "  * bssid=" MACSTR,
                           MAC2STR(params->bssid));
                if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
@@ -6260,7 +6335,7 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
                        return -1;
        }
 
-       if (params->freq.freq) {
+       if (params->freq.freq && !params->mld_params.mld_addr) {
                wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq.freq);
                if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
                                params->freq.freq))