[PATCH 19/50] AP: Support building basic Multi-Link Element
Rameshkumar Sundaram (QUIC)
quic_ramess at quicinc.com
Fri Feb 17 02:24:56 PST 2023
> -----Original Message-----
> From: Hostap <hostap-bounces at lists.infradead.org> On Behalf Of Andrei
> Otcheretianski
> Sent: Thursday, February 16, 2023 4:39 AM
> To: hostap at lists.infradead.org
> Cc: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
> Subject: [PATCH 19/50] AP: Support building basic Multi-Link Element
>
> Define a struct to hold MLD station info and implement publishing of the
> basic Multi-Link Element. Add it into beacons and probe responses.
>
> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
> ---
> src/ap/beacon.c | 23 +++++
> src/ap/ieee802_11.h | 2 +
> src/ap/ieee802_11_eht.c | 192 +++++++++++++++++++++++++++++++++++
> src/ap/sta_info.h | 34 +++++++
> src/common/ieee802_11_defs.h | 10 ++
> 5 files changed, 261 insertions(+)
>
> diff --git a/src/ap/beacon.c b/src/ap/beacon.c index
> c7ebc55347..94d68f6e70 100644
> --- a/src/ap/beacon.c
> +++ b/src/ap/beacon.c
> @@ -585,6 +585,14 @@ static u8 * hostapd_gen_probe_resp(struct
> hostapd_data *hapd,
> if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
> buflen += hostapd_eid_eht_capab_len(hapd,
> IEEE80211_MODE_AP);
> buflen += 3 + sizeof(struct ieee80211_eht_operation);
> +
> + /*
> + * TODO: multi link AP has variable length and can be
> + * long based on the common info and number of per
> + * station profiles. For now use 256.
> + */
Instead of assuming len as 256 can we determine based on link information available
> + if (hapd->conf->mld_ap)
> + buflen += 256;
> }
> #endif /* CONFIG_IEEE80211BE */
>
> @@ -727,6 +735,9 @@ static u8 * hostapd_gen_probe_resp(struct
> hostapd_data *hapd,
>
> #ifdef CONFIG_IEEE80211BE
> if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
> + if (hapd->conf->mld_ap)
> + pos = hostapd_eid_eht_basic_ml(hapd, pos, NULL,
> true);
> +
> pos = hostapd_eid_eht_capab(hapd, pos,
> IEEE80211_MODE_AP);
> pos = hostapd_eid_eht_operation(hapd, pos);
> }
> @@ -1655,6 +1666,14 @@ int ieee802_11_build_ap_params(struct
> hostapd_data *hapd,
> if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
> tail_len += hostapd_eid_eht_capab_len(hapd,
> IEEE80211_MODE_AP);
> tail_len += 3 + sizeof(struct ieee80211_eht_operation);
> +
> + /*
> + * TODO: multi link AP has variable length and can be
> + * long based on the common info and number of per
> + * station profiles. For now use 256.
> + */
> + if (hapd->conf->mld_ap)
> + tail_len += 256;
> }
> #endif /* CONFIG_IEEE80211BE */
>
> @@ -1825,6 +1844,10 @@ int ieee802_11_build_ap_params(struct
> hostapd_data *hapd,
>
> #ifdef CONFIG_IEEE80211BE
> if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
> + if (hapd->conf->mld_ap)
> + tailpos = hostapd_eid_eht_basic_ml(hapd, tailpos,
> NULL,
> + true);
> +
> tailpos = hostapd_eid_eht_capab(hapd, tailpos,
> IEEE80211_MODE_AP);
> tailpos = hostapd_eid_eht_operation(hapd, tailpos); diff --git
> a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index
> 5f443fcb8a..a5b33e7a89 100644
> --- a/src/ap/ieee802_11.h
> +++ b/src/ap/ieee802_11.h
> @@ -83,6 +83,8 @@ void hostapd_get_eht_capab(struct hostapd_data
> *hapd,
> const struct ieee80211_eht_capabilities *src,
> struct ieee80211_eht_capabilities *dest,
> size_t len);
> +u8 *hostapd_eid_eht_basic_ml(struct hostapd_data *hapd, u8 *eid,
> + struct sta_info *info, bool include_mld_id);
> int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta);
> u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta,
> const u8 *ht_capab);
> diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c index
> caaadcecf0..d5d37995ce 100644
> --- a/src/ap/ieee802_11_eht.c
> +++ b/src/ap/ieee802_11_eht.c
> @@ -408,3 +408,195 @@ void hostapd_get_eht_capab(struct hostapd_data
> *hapd,
> os_memset(dest, 0, sizeof(*dest));
> os_memcpy(dest, src, len);
> }
> +
> +u8 *hostapd_eid_eht_basic_ml(struct hostapd_data *hapd, u8 *eid,
> + struct sta_info *info, bool include_mld_id) {
> + struct wpabuf *buf;
> + u16 control;
> + u8 *pos = eid;
> + const u8 *ptr;
> + size_t len, slice_len;
> + u8 link_id;
> + u8 common_info_len;
> +
> + /*
> + * As the ML element can exceed the size of 244 bytes need to first
> + * build it and then handle defragmentation
> + */
> + buf = wpabuf_alloc(1024);
> + if (!buf)
> + return pos;
> +
> + /* set the multi-link control field */
> + control = MULTI_LINK_CONTROL_TYPE_BASIC |
> + BASIC_MULTI_LINK_CTRL_PRES_LINK_ID |
> + BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT |
> + 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 change parameter (1) + MLD EML capabilities (2) +
> + * MLD MLD capabilities (2)
> + */
> + common_info_len = 13;
> +
> + if (include_mld_id) {
> + control |= BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID;
> + common_info_len++;
> + }
> +
> + wpabuf_put_le16(buf, control);
> +
> + wpabuf_put_u8(buf, common_info_len);
> +
> + /* own MLD address */
> + wpabuf_put_data(buf, hapd->mld_addr, ETH_ALEN);
> +
> + /* own link ID */
> + wpabuf_put_u8(buf, hapd->conf->mld_link_id);
> +
> + /* currently hard code the BSS change parameters to 0x1 */
> + wpabuf_put_u8(buf, 0x1);
> +
> + wpa_printf(MSG_DEBUG, "MLD: EML capabilities=0x%x",
> + hapd->conf->mld_eml_capa);
> +
> + wpabuf_put_le16(buf, hapd->conf->mld_eml_capa);
> +
> + wpa_printf(MSG_DEBUG, "MLD: MLD capabilities=0x%x",
> + hapd->conf->mld_mld_capa);
> +
> + wpabuf_put_le16(buf, hapd->conf->mld_mld_capa);
> +
> + if (include_mld_id) {
> + wpa_printf(MSG_DEBUG, "MLD: MLD ID=0x%x", hapd->conf-
> >mld_id);
> + wpabuf_put_u8(buf, hapd->conf->mld_id);
> + }
> +
> + 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];
> + /*
> + * control (2) + station info length (1) + MAC address (6) +
> + * beacon interval (2) + TSF offset (8) + DTIM info (2) + BSS
> + * parameters change counter (1) + station profile length.
> + */
> + const size_t fixed_len = 22;
> + size_t total_len = fixed_len + link->resp_sta_profile_len;
> +
> + /* skip the local one */
> + if (link_id == hapd->conf->mld_link_id || !link->valid)
> + continue;
> +
> + wpabuf_put_u8(buf,
> EHT_ML_SUB_ELEM_PER_STA_PROFILE);
> +
> + if (total_len <= 255)
> + wpabuf_put_u8(buf, total_len);
> + else
> + wpabuf_put_u8(buf, 255);
> +
> + control = (link_id & 0xf) |
> + EHT_PER_STA_CTRL_MAC_ADDR_PRESENT_MSK |
> + EHT_PER_STA_CTRL_COMPLETE_PROFILE_MSK |
> + EHT_PER_STA_CTRL_TSF_OFFSET_PRESENT_MSK |
> +
> EHT_PER_STA_CTRL_BEACON_INTERVAL_PRESENT_MSK |
> + EHT_PER_STA_CTRL_DTIM_INFO_PRESENT_MSK |
> +
> EHT_PER_STA_CTRL_BSS_PARAM_CNT_PRESENT_MSK;
> +
> + wpabuf_put_le16(buf, control);
> +
> + /* STA info length */
> + wpabuf_put_u8(buf, fixed_len - 2);
> +
> + wpabuf_put_data(buf, link->local_addr, ETH_ALEN);
> +
> + /* TODO: currently assume same beacon interval */
We use the first link hapd and use its config/parameters for all the link station. Rather can we have a list to identify the partner hapd and update the same?
> + wpabuf_put_le16(buf, hapd->iconf->beacon_int);
More information about the Hostap
mailing list