wlan-ap-Telecominfraproject/feeds/qca/hostapd/patches/r02-002-hostapd-MLO-MBSSID-Support.patch
John Crispin 008ca9618d
Some checks failed
Build OpenWrt/uCentral images / build (cig_wf186h) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf186w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf188n) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf189) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf196) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-a1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-b1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap102) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap104) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap105) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap111) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap112) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_3) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xe) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (indio_um-305ax) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sercomm_ap72tip) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630c-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-211g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-id2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-od2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr5018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018-v4) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax820) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax840) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap640) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap650) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap655) (push) Has been cancelled
Build OpenWrt/uCentral images / trigger-testing (push) Has been cancelled
Build OpenWrt/uCentral images / create-x64_vm-ami (push) Has been cancelled
ipq95xx: import ath12.4-cs kernel and drivers
Signed-off-by: John Crispin <john@phrozen.org>
2024-10-20 09:25:13 +02:00

590 lines
19 KiB
Diff

From 889047335722d6cabaea8a56fa0445ddc2048d11 Mon Sep 17 00:00:00 2001
From: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Date: Thu, 12 Oct 2023 23:25:59 +0530
Subject: [PATCH] hostapd: MLO MBSSID Support
For an ML AP single interface can have multiple links and any
of links can be a TX link for other ML/NON-ML APs in same
radio those forming an MBSSID group.
Hence if Tx interface of a non-tx AP is an ML AP,
then link id of the corresponding transmitting link inside
that TX ML AP has to be notified while starting non-tx vdev,
so that the kernel can map tx vdev and tx link for this non-tx AP.
Add additional attribute and send tx link id along tx ifindex
in non-transmitting AP START CMD.
For beacon Add ML IE for Non-tx profie inside MBSSID non-tx bss
profile sub element if it is an MLD.
For Probe response Solicited MLD APs MLE should be added in the frame body
of the multi-link probe response, add the same.
Add MLD information in RNR partial profile TBTTs as well as ML Partner
reporting TBTTs if reported AP is an MLD AP with right mld id.
Currently bssid given in config file is used as mld address and
link address/bssid is randomized, this breaks MBSSID addressing
pattern.
Fix link address usage in MLD bring up to use bssid
given in config as such and use first link bssid as ML Address for
that MLD.
While building ML IE for beacon and probe, length of 256 is allocated
statically but for EMA length of MBSSID IE determines the periodicity
and hence considering a static length for non transmitting profile's ML IE
affects the whole EMA logic.
Fix this by calculating the exact length of ML IE that is to be added for
a BSS.
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
---
hostapd/main.c | 7 +-
src/ap/beacon.c | 8 +++
src/ap/hostapd.c | 12 ++--
src/ap/ieee802_11.c | 128 +++++++++++++++++++++++++----------
src/ap/ieee802_11.h | 2 +
src/ap/ieee802_11_eht.c | 82 +++++++++++++++++++---
src/drivers/driver.h | 7 ++
src/drivers/driver_nl80211.c | 35 +++-------
8 files changed, 201 insertions(+), 80 deletions(-)
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -490,6 +490,10 @@ ieee802_11_build_ap_params_mbssid(struct
goto fail;
tx_bss = hostapd_mbssid_get_tx_bss(hapd);
+ if (tx_bss->conf->mld_ap)
+ params->mbssid_tx_iface_linkid = tx_bss->mld_link_id;
+ else
+ params->mbssid_tx_iface_linkid = -1;
len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count,
NULL, 0, &rnr_len);
if (!len || (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED &&
@@ -632,6 +636,8 @@ static u8 * hostapd_gen_probe_resp(struc
buflen += (6 + 2 + 4 +
sizeof(struct ieee80211_240mhz_vendor_oper));
}
+ if (hapd_probed != hapd && hapd_probed->conf->mld_ap)
+ buflen += hostapd_eid_eht_basic_ml_len(hapd_probed, NULL, true);
#endif /* CONFIG_IEEE80211BE */
buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL,
@@ -801,6 +807,8 @@ static u8 * hostapd_gen_probe_resp(struc
pos = hostapd_eid_eht_operation(hapd, pos, IEEE80211_MODE_AP);
pos = hostapd_eid_vendor_240mhz(hapd, pos, IEEE80211_MODE_AP);
}
+ if (hapd_probed != hapd && hapd_probed->conf->mld_ap)
+ pos = hostapd_eid_eht_basic_ml(hapd_probed, pos, NULL, true);
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_IEEE80211AC
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1269,6 +1269,8 @@ static int hostapd_start_beacon(struct h
WLAN_REASON_PREV_AUTH_NOT_VALID);
}
+ if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
+ return -1;
if (hapd->driver && hapd->driver->set_operstate)
hapd->driver->set_operstate(hapd->drv_priv, 1);
@@ -1336,6 +1338,7 @@ static int hostapd_setup_bss(struct host
/* Allocate the configured BSSID. */
os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN);
+
if (hostapd_mac_comp(hapd->own_addr,
hapd->iface->bss[0]->own_addr) ==
0) {
@@ -1644,9 +1647,6 @@ setup_mld:
if (start_beacon && hostapd_start_beacon(hapd, flush_old_stations) < 0)
return -1;
- if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
- return -1;
-
return 0;
}
@@ -4853,10 +4853,7 @@ u8 hostapd_get_mld_id(struct hostapd_dat
if (!hapd->conf->mld_ap)
return 255;
- /* MLD ID 0 represents self */
- return 0;
-
- /* TODO MLD ID for MBSS cases */
+ return hostapd_mbssid_get_bss_index(hapd);
}
int hostapd_mld_add_link(struct hostapd_data *hapd)
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -7256,6 +7256,37 @@ static size_t hostapd_eid_nr_db_len(stru
return total_len;
}
+bool hostapd_mbssid_mld_match(struct hostapd_data *tx_hapd,
+ struct hostapd_data *ml_hapd, u8 *match_idx)
+{
+ int bss_idx = 0;
+ struct hostapd_data *bss;
+
+ if (!ml_hapd->conf->mld_ap)
+ return false;
+
+ if (!tx_hapd->iconf->mbssid || tx_hapd->iface->num_bss <= 1) {
+ if (hostapd_is_ml_partner(tx_hapd, ml_hapd)) {
+ if (match_idx)
+ *match_idx = 0;
+ return true;
+ } else
+ return false;
+ }
+
+ for (bss_idx = 0; bss_idx < tx_hapd->iface->num_bss; bss_idx++) {
+ bss = tx_hapd->iface->bss[bss_idx];
+ if (!bss)
+ continue;
+
+ if (hostapd_is_ml_partner(bss, ml_hapd)) {
+ if (match_idx)
+ *match_idx = bss_idx;
+ return true;
+ }
+ }
+ return false;
+}
struct mbssid_ie_profiles {
u8 start;
@@ -7292,6 +7323,7 @@ repeat_rnr_len:
for (i = start; i < hapd->iface->num_bss; i++) {
struct hostapd_data *bss = hapd->iface->bss[i];
bool ap_mld = false;
+ u8 match_idx;
if (!bss || !bss->conf || !bss->started)
continue;
@@ -7304,7 +7336,7 @@ repeat_rnr_len:
bss->conf->ignore_broadcast_ssid)
continue;
- if (skip_profiles &&
+ if (!mld_update && skip_profiles &&
i >= skip_profiles->start && i < skip_profiles->end)
continue;
@@ -7329,9 +7361,17 @@ repeat_rnr_len:
/* If building for ML RNR and they are not ML parnters,
* don't include.
*/
- if (mld_update && !hostapd_is_ml_partner(reporting_hapd, bss))
+ if (mld_update && !hostapd_mbssid_mld_match(reporting_hapd, bss, &match_idx))
continue;
+ /* When MLD params are added to beacon RNR and in case of EMA beacons
+ * we report only affiliated APs belonging to the reported non Tx profiles
+ * And TX profile will reported in every EMA beacon.
+ */
+ if (mld_update && skip_profiles && match_idx &&
+ ((match_idx < skip_profiles->start) || (match_idx >= skip_profiles->end)))
+ continue;
+
if (len + tbtt_info_len > 255 ||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
break;
@@ -7439,6 +7479,7 @@ static size_t hostapd_eid_rnr_colocation
}
static size_t hostapd_eid_rnr_mlo_len(struct hostapd_data *hapd, u32 type,
+ struct mbssid_ie_profiles *skip_profiles,
size_t *current_len)
{
struct hostapd_iface *iface;
@@ -7448,9 +7489,6 @@ static size_t hostapd_eid_rnr_mlo_len(st
if (!hapd->iface || !hapd->iface->interfaces)
return 0;
- if (!hapd->conf->mld_ap)
- return 0;
-
/* TODO allow for FILS/Action as well */
if (type != WLAN_FC_STYPE_BEACON && type != WLAN_FC_STYPE_PROBE_RESP)
return 0;
@@ -7465,7 +7503,7 @@ static size_t hostapd_eid_rnr_mlo_len(st
continue;
len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
- current_len, NULL, true);
+ current_len, skip_profiles, true);
}
#endif /* CONFIG_IEEE80211BE */
return len;
@@ -7505,9 +7543,10 @@ size_t hostapd_eid_rnr_len(struct hostap
break;
}
- /* For EMA Beacons, MLD neighbor repoting is added as part of mbssid rnr */
- if (include_mld_params && (type != WLAN_FC_STYPE_BEACON || !hapd->iconf->ema))
- total_len += hostapd_eid_rnr_mlo_len(hapd, type, &current_len);
+ /* For EMA Beacons, MLD neighbor reporting is added as part of mbssid rnr */
+ if (include_mld_params && (type != WLAN_FC_STYPE_BEACON ||
+ hapd->iconf->mbssid != ENHANCED_MBSSID_ENABLED))
+ total_len += hostapd_eid_rnr_mlo_len(hapd, type, NULL, &current_len);
return total_len;
}
@@ -7583,7 +7622,7 @@ static u8 * hostapd_eid_rnr_iface(struct
u8 tbtt_count, total_tbtt_count = 0, op_class, channel, bss_param;
u8 tbtt_info_len = mld_update ? RNR_TBTT_INFO_MLD_LEN : RNR_TBTT_INFO_LEN;
u8 bss_param_change_count = 0;
- bool ap_mld, is_partner;
+ bool ap_mld;
if (!(iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || !iface->freq)
return eid;
@@ -7614,6 +7653,7 @@ repeat_rnr:
for (i = start; i < iface->num_bss; i++) {
ap_mld = false;
+ u8 match_idx = 255;
bss_param = 0;
bss = iface->bss[i];
@@ -7628,7 +7668,7 @@ repeat_rnr:
bss->conf->ignore_broadcast_ssid)
continue;
- if (skip_profiles &&
+ if (!mld_update && skip_profiles &&
i >= skip_profiles->start && i < skip_profiles->end)
continue;
@@ -7653,9 +7693,18 @@ repeat_rnr:
/* If building for ML RNR and they are not ML parnters,
* don't include.
*/
- if (mld_update && !hostapd_is_ml_partner(reporting_hapd, bss))
+ if (mld_update && !hostapd_mbssid_mld_match(reporting_hapd, bss, &match_idx))
continue;
+ /* When MLD params are added to beacon RNR and in case of EMA beacons
+ * we report only affiliated APs belonging to the reported non Tx profiles
+ * And TX profile will reported in every EMA beacon.
+ */
+
+ if (mld_update && skip_profiles && match_idx &&
+ ((match_idx < skip_profiles->start) || (match_idx >= skip_profiles->end)))
+ continue;
+
if (len + tbtt_info_len > 255 ||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
break;
@@ -7701,23 +7750,24 @@ repeat_rnr:
if (ap_mld) {
#ifdef CONFIG_IEEE80211BE
- /* If bss is not partner of the reporting_hapd then
+ /* If bss is not partner of the reporting_hapd
+ * or its one of non tx hapd then,
* a) MLD ID advertised shall be 255.
* b) Link ID advertised shall be 15.
* c) BPCC advertised shall be 255
*/
- is_partner = hostapd_is_ml_partner(bss, reporting_hapd);
/* MLD ID */
- *eid++ = is_partner ? hostapd_get_mld_id(bss) : 255;
+ *eid++ = match_idx;
/* Link ID (Bit 3 to Bit 0)
* BPCC (Bit 4 to Bit 7)
*/
- *eid++ = is_partner ?
+ *eid++ = match_idx < 255 ?
bss->mld_link_id | ((bss_param_change_count & 0xf) << 4) :
MAX_NUM_MLD_LINKS | 0xf0;
/* BPCC (Bit 3 to Bit 0) */
- *eid++ = is_partner ? ((bss_param_change_count & 0xf0) >> 4) :
- 0x0f;
+ *eid++ = match_idx < 255 ?
+ ((bss_param_change_count & 0xf0) >> 4) :
+ 0x0f;
#endif /* CONFIG_IEEE80211BE */
}
@@ -7774,7 +7824,8 @@ u8 * hostapd_eid_rnr_colocation(struct h
}
u8 * hostapd_eid_rnr_mlo(struct hostapd_data *hapd, u32 type,
- u8 *eid, size_t *current_len)
+ u8 *eid, struct mbssid_ie_profiles *skip_profiles,
+ size_t *current_len)
{
struct hostapd_iface *iface;
size_t i;
@@ -7783,9 +7834,6 @@ u8 * hostapd_eid_rnr_mlo(struct hostapd_
if (!hapd->iface || !hapd->iface->interfaces)
return eid;
- if (!hapd->conf->mld_ap)
- return eid;
-
/* TODO allow for FILS/Action as well */
if (type != WLAN_FC_STYPE_BEACON && type != WLAN_FC_STYPE_PROBE_RESP)
return eid;
@@ -7800,7 +7848,7 @@ u8 * hostapd_eid_rnr_mlo(struct hostapd_
continue;
eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
- current_len, NULL, true);
+ current_len, skip_profiles, true);
}
#endif /* CONFIG_IEEE80211BE */
return eid;
@@ -7841,9 +7889,10 @@ u8 * hostapd_eid_rnr(struct hostapd_data
return eid_start;
}
- /* For EMA Beacons, MLD neighbor repoting is added as part of mbssid rnr */
- if (include_mld_params && (type != WLAN_FC_STYPE_BEACON || !hapd->iconf->ema))
- eid = hostapd_eid_rnr_mlo(hapd, type, eid, &current_len);
+ /* For EMA Beacons, MLD neighbor reporting is added as part of mbssid rnr */
+ if (include_mld_params && (type != WLAN_FC_STYPE_BEACON ||
+ hapd->iconf->mbssid != ENHANCED_MBSSID_ENABLED))
+ eid = hostapd_eid_rnr_mlo(hapd, type, eid, NULL, &current_len);
if (eid == eid_start + 2)
return eid_start;
@@ -7928,6 +7977,11 @@ static size_t hostapd_eid_mbssid_elem_le
nontx_profile_len += xrate_len;
else if (tx_xrate_len)
ie_count++;
+
+ /* For ML Probe resp, solicited hapd's MLE will be in the frame body */
+ if (bss->conf->mld_ap && (bss != hapd || frame_type != WLAN_FC_STYPE_PROBE_RESP))
+ nontx_profile_len += hostapd_eid_eht_basic_ml_len(bss, NULL, true);
+
if (ie_count)
nontx_profile_len += 4 + ie_count;
@@ -7949,11 +8003,6 @@ size_t hostapd_eid_mbssid_len(struct hos
size_t known_bss_len, size_t *rnr_len)
{
size_t len = 0, bss_index = 1;
- bool ap_mld = false;
-
-#ifdef CONFIG_IEEE80211BE
- ap_mld = !!hapd->conf->mld_ap;
-#endif /* CONFIG_IEEE80211BE */
if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 ||
(frame_type != WLAN_FC_STYPE_BEACON &&
@@ -7986,7 +8035,11 @@ size_t hostapd_eid_mbssid_len(struct hos
*rnr_len += hostapd_eid_rnr_iface_len(
hapd, hostapd_mbssid_get_tx_bss(hapd),
- &rnr_cur_len, &skip_profiles, ap_mld);
+ &rnr_cur_len, &skip_profiles, false);
+
+ *rnr_len += hostapd_eid_rnr_mlo_len(
+ hostapd_mbssid_get_tx_bss(hapd), frame_type,
+ &skip_profiles, &rnr_cur_len);
}
}
@@ -8085,6 +8138,9 @@ static u8 * hostapd_eid_mbssid_elem(stru
non_inherit_ie[ie_count++] = WLAN_EID_RSNX;
if (tx_xrate_len && !xrate_len)
non_inherit_ie[ie_count++] = WLAN_EID_EXT_SUPP_RATES;
+ /* For ML Probe resp, solicited hapd's MLE will be in the frame body */
+ if (bss->conf->mld_ap && (bss != hapd || frame_type != WLAN_FC_STYPE_PROBE_RESP))
+ eid = hostapd_eid_eht_basic_ml(bss, eid, NULL, true);
if (ie_count) {
*eid++ = WLAN_EID_EXTENSION;
*eid++ = 2 + ie_count;
@@ -8119,11 +8175,7 @@ u8 * hostapd_eid_mbssid(struct hostapd_d
{
size_t bss_index = 1, cur_len = 0;
u8 elem_index = 0, *rnr_start_eid = rnr_eid;
- bool add_rnr, ap_mld;
-
-#ifdef CONFIG_IEEE80211BE
- ap_mld = !!hapd->conf->mld_ap;
-#endif /* CONFIG_IEEE80211BE */
+ bool add_rnr;
if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 ||
(frame_stype != WLAN_FC_STYPE_BEACON &&
@@ -8168,7 +8220,10 @@ u8 * hostapd_eid_mbssid(struct hostapd_d
cur_len = 0;
rnr_eid = hostapd_eid_rnr_iface(
hapd, hostapd_mbssid_get_tx_bss(hapd),
- rnr_eid, &cur_len, &skip_profiles, ap_mld);
+ rnr_eid, &cur_len, &skip_profiles, false);
+ rnr_eid = hostapd_eid_rnr_mlo(
+ hostapd_mbssid_get_tx_bss(hapd), frame_stype,
+ rnr_eid, &skip_profiles, &cur_len);
}
}
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -98,6 +98,8 @@ void hostapd_get_eht_capab(struct hostap
size_t len);
u8 * hostapd_eid_eht_basic_ml(struct hostapd_data *hapd, u8 *eid,
struct sta_info *info, bool include_mld_id);
+size_t hostapd_eid_eht_basic_ml_len(struct hostapd_data *hapd,
+ struct sta_info *info, bool include_mld_id);
struct wpabuf * hostapd_ml_auth_resp(struct hostapd_data *hapd);
const u8 * hostapd_process_ml_auth(struct hostapd_data *hapd,
const struct ieee80211_mgmt *mgmt,
--- a/src/ap/ieee802_11_eht.c
+++ b/src/ap/ieee802_11_eht.c
@@ -546,7 +546,12 @@ void hostapd_get_eht_capab(struct hostap
os_memcpy(dest, src, len);
}
-
+/* Beacon or a non ML Probe response should include
+ * Common Info Length(1) + MLD MAC Address(6) +
+ * Link ID Info(1) + BSS Parameters Change count(1) +
+ * EML Capabilities (2) + MLD Capabilities (2)
+*/
+#define MLE_COMMON_INFO_LEN 13
u8 * hostapd_eid_eht_basic_ml(struct hostapd_data *hapd, u8 *eid,
struct sta_info *info, bool include_mld_id)
{
@@ -573,14 +578,7 @@ u8 * hostapd_eid_eht_basic_ml(struct hos
BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA |
BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA;
- /*
- * Set the basic Multi-Link common information. Hard code the common
- * info length to 13 based on the length of the present fields:
- * Length (1) + MLD address (6) + Link ID (1) +
- * BSS Parameters Change Count (1) + EML Capabilities (2) +
- * MLD Capabilities and Operations (2)
- */
- common_info_len = 13;
+ common_info_len = MLE_COMMON_INFO_LEN;
if (include_mld_id) {
/* AP MLD ID */
@@ -749,6 +747,72 @@ out:
wpabuf_free(buf);
return pos;
}
+#define MLE_STA_INFO_LENGTH 22
+/*
+ * control (2) + station info length (1) + MAC address (6) +
+ * beacon interval (2) + TSF offset (8) + DTIM info (2) + BSS
+ * parameters change counter (1)
+ */
+size_t hostapd_eid_eht_basic_ml_len(struct hostapd_data *hapd,
+ struct sta_info *info,
+ bool include_mld_id)
+{
+ int link_id;
+ size_t len, num_frags;
+
+ if (!hapd->conf->mld_ap)
+ return 0;
+
+ /* Include WLAN_EID_EXT_MULTI_LINK (1) */
+ len = 1;
+ /* control field */
+ len += 2;
+ /* Common info len for Basic MLE */
+ len += MLE_COMMON_INFO_LEN;
+ if (include_mld_id)
+ len++;
+
+ if (!info)
+ goto out;
+
+ /* Add link info for the other links */
+ for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
+ struct mld_link_info *link = &info->mld_info.links[link_id];
+ struct hostapd_data *link_bss;
+
+ size_t sta_prof_len = MLE_STA_INFO_LENGTH + link->resp_sta_profile_len;
+
+ /* Skip the local one */
+ if (link_id == hapd->mld_link_id || !link->valid)
+ continue;
+
+ link_bss = hostapd_mld_get_link_bss(hapd, link_id);
+ if (!link_bss) {
+ wpa_printf(MSG_ERROR,
+ "MLD: Couldn't find link BSS - skip it");
+ continue;
+ }
+
+ /* Per-STA Profile Subelement(1), Length (1) */
+ len += 2;
+ len += sta_prof_len;
+ /* Consider Frag EID(1) and Length (1) for each subelement fragement. */
+ if (sta_prof_len > 255) {
+ num_frags = ((sta_prof_len / 255) - 1) + !!(sta_prof_len % 255);
+ len += (num_frags * 2);
+ }
+
+ }
+
+out:
+ if (len > 255) {
+ num_frags = ((len / 255) - 1) + !!(len % 255);
+ len += (num_frags * 2);
+ }
+
+ /*WLAN_EID_EXTENSION (1) + length (1) */
+ return len + 2;
+}
struct wpabuf * hostapd_ml_auth_resp(struct hostapd_data *hapd)
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1805,6 +1805,13 @@ struct wpa_driver_ap_params {
const char *mbssid_tx_iface;
/**
+ * mbssid_tx_iface_linkid linkid which is Transmitting interface
+ * for this non-tx link if mbssid_tx_iface is an MLD
+ */
+
+ int mbssid_tx_iface_linkid;
+
+ /**
* mbssid_index - The index of this BSS in the MBSSID set
*/
unsigned int mbssid_index;
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -694,7 +694,11 @@ static struct nl_msg *
nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex,
int flags, uint8_t cmd)
{
- return nl80211_ifindex_msg_build(drv, nlmsg_alloc(), ifindex, flags,
+ /* WAR: Increasing max buffer size since nla_reserve() in libnl-tiny
+ * needs twice the current consumed length to be available for any attribute to be
+ * added. Fix it properly and remove this.
+ */
+ return nl80211_ifindex_msg_build(drv, nlmsg_alloc_size(getpagesize() * 2), ifindex, flags,
cmd);
}
@@ -4802,6 +4806,9 @@ static int nl80211_mbssid(struct nl_msg
nla_put_u32(msg, NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX,
ifidx))
return -1;
+ if (params->mbssid_tx_iface_linkid >= 0)
+ nla_put_u8(msg, NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID,
+ params->mbssid_tx_iface_linkid);
}
if (params->ema && nla_put_flag(msg, NL80211_MBSSID_CONFIG_ATTR_EMA))