]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
ctrl_iface: Report RNR and ML in BSS command
authorIlan Peer <ilan.peer@intel.com>
Wed, 30 Nov 2022 13:09:26 +0000 (15:09 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 3 Dec 2022 09:47:07 +0000 (11:47 +0200)
Add the required ML and RNR definitions and report the information in
BSS command.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
src/common/ieee802_11_defs.h
src/common/wpa_ctrl.h
wpa_supplicant/ctrl_iface.c

index dbb0691af4714769e7ee24c6a628edb558c115b0..6ded79deca7bcdb7ff53f36c57dcdaa75634fa80 100644 (file)
@@ -2570,6 +2570,92 @@ struct ieee80211_eht_capabilities {
 
 #define BASIC_MLE_STA_PROF_STA_MAC_IDX                 3
 
+/* IEEE P802.11be/D2.2, 9.4.2.312.2.3 - Common Info field of the Basic
+ * Multi-Link element */
+struct eht_ml_basic_common_info {
+       u8 len;
+       u8 mld_addr[ETH_ALEN];
+
+       /*
+        * Followed by optional fields based on the multi link basic presence
+        * bitmap
+        *
+        * Link ID Info: 1 octet
+        * BSS Parameters Change Count: 1 octet
+        * Medium Synchronization Delay Information: 2 octets
+        * EML Capabilities: 2 octets
+        * MLD Capabilities and Operations: 2 octets
+        * AP MLD ID: 1 octet
+        */
+       u8 variable[];
+} STRUCT_PACKED;
+
+#define EHT_ML_LINK_ID_MSK   0x0f
+
+#define EHT_ML_MEDIUM_SYNC_DELAY_DURATION   0x00ff
+#define EHT_ML_MEDIUM_SYNC_DELAY_OFDM_ED_TH 0x0f00
+#define EHT_ML_MEDIUM_SYNC_DELAY_MAX_TXOP   0xf000
+
+#define EHT_ML_EML_CAPA_EMLSR_SUPP               0x0001
+#define EHT_ML_EML_CAPA_EMLSR_PADDING_DELAY_MASK 0x000e
+#define EHT_ML_EML_CAPA_EMLSR_TRANS_DELAY_MASK   0x0070
+#define EHT_ML_EML_CAPA_EMLMR_SUPP               0x0080
+#define EHT_ML_EML_CAPA_EMLMR_DELAY_MASK         0x0700
+#define EHT_ML_EML_CAPA_TRANSITION_TIMEOUT_MASK  0x7800
+
+#define EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK        0x000f
+#define EHT_ML_MLD_CAPA_SRS_SUPP                      0x0010
+#define EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_ALL_TO_ALL    0x0020
+#define EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_ALL_TO_ONE    0x0040
+#define EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_NEG_SUPP_MSK  0x0060
+#define EHT_ML_MLD_CAPA_FREQ_SEP_FOR_STR_MASK         0x0f80
+#define EHT_ML_MLD_CAPA_AAR_SUPP                      0x1000
+
+/* IEEE P802.11be/D2.0, 9.4.2.312.2.4 - Per-STA Profile subelement format */
+struct ieee80211_eht_per_sta_profile {
+       le16 sta_control;
+
+       /* Followed by STA Info and STA Profile fields */
+       u8 variable[];
+} STRUCT_PACKED;
+
+/* IEEE P802.11be/D2.0, 9.4.2.312.3 - Probe Request Multi-Link element */
+
+#define EHT_ML_PRES_BM_PROBE_REQ_AP_MLD_ID 0x0001
+
+struct eht_ml_probe_req_common_info {
+       u8 len;
+
+       /*
+        * Followed by optional fields based on the multi link basic presence
+        * bitmap
+        *
+        * AP MLD ID: 1 octet
+        */
+       u8 variable[];
+} STRUCT_PACKED;
+
+/* IEEE P802.11be/D2.0, 9.4.2.312.4 - Reconfiguration Multi-Link element */
+
+#define EHT_ML_PRES_BM_RECONFIGURE_MLD_ADDRESS 0x0001
+
+/* IEEE P802.11be/D2.0, 9.4.2.312.1 - Multi-Link element / General */
+
+struct ieee80211_eht_ml {
+       le16 ml_control;
+
+       /* Followed by Common Info and Link Info fields */
+       u8 variable[];
+} STRUCT_PACKED;
+
+/* Table 9-401c - Optional subelement IDs for Link Info field of the
+ * Multi-Link element */
+enum ieee80211_eht_ml_sub_elem {
+       EHT_ML_SUB_ELEM_PER_STA_PROFILE = 0,
+       EHT_ML_SUB_ELEM_VENDOR = 221,
+       EHT_ML_SUB_ELEM_FRAGMENT = 254,
+};
+
 /* IEEE P802.11ay/D4.0, 9.4.2.251 - EDMG Operation element */
 #define EDMG_BSS_OPERATING_CHANNELS_OFFSET     6
 #define EDMG_OPERATING_CHANNEL_WIDTH_OFFSET    7
@@ -2711,4 +2797,14 @@ enum dscp_policy_request_type {
 #define WFA_CAPA_QM_DSCP_POLICY BIT(0)
 #define WFA_CAPA_QM_UNSOLIC_DSCP BIT(1)
 
+struct ieee80211_neighbor_ap_info {
+       u8 tbtt_info_hdr;
+       u8 tbtt_info_len;
+       u8 op_class;
+       u8 channel;
+
+       /* Followed by the rest of the TBTT Information field contents */
+       u8 data[0];
+} STRUCT_PACKED;
+
 #endif /* IEEE802_11_DEFS_H */
index ba54da544fe845dc89a811e941fcfe69fdbcf5bf..4ab2a1b634ccf6c849efd2b76166b8190d806df9 100644 (file)
@@ -466,6 +466,8 @@ extern "C" {
 #define WPA_BSS_MASK_UPDATE_IDX                BIT(22)
 #define WPA_BSS_MASK_BEACON_IE         BIT(23)
 #define WPA_BSS_MASK_FILS_INDICATION   BIT(24)
+#define WPA_BSS_MASK_RNR               BIT(25)
+#define WPA_BSS_MASK_ML                        BIT(26)
 
 
 /* VENDOR_ELEM_* frame id values */
index cf2f4b821d4fb70b195c87127ef87dc6163bc1e9..d34d4a7778d5d5f3c69296433d648696b2e0c524 100644 (file)
@@ -5001,6 +5001,250 @@ static int print_fils_indication(struct wpa_bss *bss, char *pos, char *end)
 #endif /* CONFIG_FILS */
 
 
+static int print_rnr(struct wpa_bss *bss, char *pos, char *end)
+{
+       char *start = pos;
+       const u8 *ie, *ie_end;
+       unsigned int n = 0;
+       int ret;
+
+       ie = wpa_bss_get_ie(bss, WLAN_EID_REDUCED_NEIGHBOR_REPORT);
+       if (!ie)
+               return 0;
+
+       ie_end = ie + 2 + ie[1];
+       ie += 2;
+
+       while (ie < ie_end) {
+               const struct ieee80211_neighbor_ap_info *info =
+                       (const struct ieee80211_neighbor_ap_info *) ie;
+               const u8 *tbtt_start;
+               size_t left = ie_end - ie;
+
+               if (left < sizeof(struct ieee80211_neighbor_ap_info))
+                       return 0;
+
+               left -= sizeof(struct ieee80211_neighbor_ap_info);
+               if (left < info->tbtt_info_len)
+                       return 0;
+
+               ret = os_snprintf(pos, end - pos,
+                                 "ap_info[%u]: tbtt_info: hdr=0x%x, len=%u, op_c=%u, channel=%u, ",
+                                 n, *ie, info->tbtt_info_len,
+                                 info->op_class, info->channel);
+               if (os_snprintf_error(end - pos, ret))
+                       return 0;
+               pos += ret;
+
+               ie += sizeof(struct ieee80211_neighbor_ap_info);
+               tbtt_start = ie;
+               if (info->tbtt_info_len >= 1) {
+                       ret = os_snprintf(pos, end - pos,
+                                         "tbtt_offset=%u, ", *ie);
+                       if (os_snprintf_error(end - pos, ret))
+                               return 0;
+
+                       ie++;
+                       pos += ret;
+               }
+
+               if (info->tbtt_info_len >= 7) {
+                       ret = os_snprintf(pos, end - pos,
+                                         "bssid=" MACSTR ", ",
+                                         MAC2STR(ie));
+                       if (os_snprintf_error(end - pos, ret))
+                               return 0;
+
+                       ie += ETH_ALEN;
+                       pos += ret;
+               }
+
+               if (info->tbtt_info_len >= 11) {
+                       ret = os_snprintf(pos, end - pos,
+                                         "short SSID=0x%x, ",
+                                         WPA_GET_LE32(ie));
+                       if (os_snprintf_error(end - pos, ret))
+                               return 0;
+
+                       ie += 4;
+                       pos += ret;
+               }
+
+               if (info->tbtt_info_len >= 12) {
+                       ret = os_snprintf(pos, end - pos,
+                                         "bss_params=0x%x, ", *ie);
+                       if (os_snprintf_error(end - pos, ret))
+                               return 0;
+
+                       ie++;
+                       pos += ret;
+               }
+
+               if (info->tbtt_info_len >= 13) {
+                       ret = os_snprintf(pos, end - pos,
+                                         "PSD=0x%x, ", *ie);
+                       if (os_snprintf_error(end - pos, ret))
+                               return 0;
+
+                       ie++;
+                       pos += ret;
+               }
+
+               if (info->tbtt_info_len >= 16) {
+                       ret = os_snprintf(pos, end - pos,
+                                         "mld ID=%u, link ID=%u",
+                                         *ie, *(ie + 1) & 0xF);
+                       if (os_snprintf_error(end - pos, ret))
+                               return 0;
+
+                       ie += 3;
+                       pos += ret;
+               }
+
+               ie = tbtt_start + info->tbtt_info_len;
+
+               ret = os_snprintf(pos, end - pos, "\n");
+               if (os_snprintf_error(end - pos, ret))
+                       return 0;
+               pos += ret;
+
+               n++;
+       }
+
+       return pos - start;
+}
+
+
+static int print_ml(struct wpa_bss *bss, char *pos, char *end)
+{
+       const struct ieee80211_eht_ml *ml;
+       char *start = pos;
+       const u8 *ie, *ie_end;
+       u16 ml_control;
+       u8 common_info_length;
+       int ret;
+
+       ie = get_ml_ie(wpa_bss_ie_ptr(bss), bss->ie_len,
+                      MULTI_LINK_CONTROL_TYPE_BASIC);
+       if (!ie)
+               return 0;
+
+       ie_end = ie + 2 + ie[1];
+       ie += 3;
+       ml = (const struct ieee80211_eht_ml *) ie;
+
+       /* control + common info length + MLD MAC Address */
+       if (ie_end - ie < 2 + 1 + ETH_ALEN)
+               return 0;
+
+       ml_control = le_to_host16(ml->ml_control);
+
+       common_info_length = *(ie + 2);
+       ret = os_snprintf(pos, end - pos,
+                         "multi-link: control=0x%x, common info len=%u",
+                         ml_control, common_info_length);
+       if (os_snprintf_error(end - pos, ret))
+               return 0;
+       pos += ret;
+
+       ie += 2;
+       if (ie_end - ie < common_info_length)
+               return 0;
+
+       ie++;
+       common_info_length--;
+
+       if (common_info_length < ETH_ALEN)
+               return 0;
+
+       ret = os_snprintf(pos, end - pos, ", MLD addr=" MACSTR, MAC2STR(ie));
+       if (os_snprintf_error(end - pos, ret))
+               return 0;
+       pos += ret;
+
+       ie += ETH_ALEN;
+       common_info_length -= ETH_ALEN;
+
+       if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_LINK_ID) {
+               if (common_info_length < 1)
+                       return 0;
+
+               ret = os_snprintf(pos, end - pos, ", link ID=%u", *ie & 0x0f);
+               if (os_snprintf_error(end - pos, ret))
+                       return 0;
+               pos += ret;
+               ie++;
+               common_info_length--;
+       }
+
+       if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT) {
+               if (common_info_length < 1)
+                       return 0;
+
+               ret = os_snprintf(pos, end - pos,
+                                 ", BSS change parameters=0x%x", *ie);
+               if (os_snprintf_error(end - pos, ret))
+                       return 0;
+               pos += ret;
+               ie++;
+               common_info_length--;
+       }
+
+       if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO) {
+               if (common_info_length < 2)
+                       return 0;
+
+               ret = os_snprintf(pos, end - pos, ", MSD Info=0x%x",
+                                 WPA_GET_LE16(ie));
+               if (os_snprintf_error(end - pos, ret))
+                       return 0;
+               pos += ret;
+               ie += 2;
+               common_info_length -= 2;
+       }
+
+       if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA) {
+               if (common_info_length < 2)
+                       return 0;
+
+               ret = os_snprintf(pos, end - pos, ", EML capabilities=0x%x",
+                                 WPA_GET_LE16(ie));
+               if (os_snprintf_error(end - pos, ret))
+                       return 0;
+               pos += ret;
+               ie += 2;
+               common_info_length -= 2;
+       }
+
+       if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA) {
+               if (common_info_length < 2)
+                       return 0;
+
+               ret = os_snprintf(pos, end - pos, ", MLD capabilities=0x%x",
+                                 WPA_GET_LE16(ie));
+               if (os_snprintf_error(end - pos, ret))
+                       return 0;
+               pos += ret;
+               ie += 2;
+               common_info_length -= 2;
+       }
+
+       if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID) {
+               if (common_info_length < 1)
+                       return 0;
+
+               ret = os_snprintf(pos, end - pos, ", MLD ID=0x%x\n", *ie);
+               if (os_snprintf_error(end - pos, ret))
+                       return 0;
+               pos += ret;
+               ie += 1;
+               common_info_length--;
+       }
+
+       return pos - start;
+}
+
+
 static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
                          unsigned long mask, char *buf, size_t buflen)
 {
@@ -5451,6 +5695,12 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
                pos += ret;
        }
 
+       if (mask & WPA_BSS_MASK_RNR)
+               pos += print_rnr(bss, pos, end);
+
+       if (mask & WPA_BSS_MASK_ML)
+               pos += print_ml(bss, pos, end);
+
        if (mask & WPA_BSS_MASK_DELIM) {
                ret = os_snprintf(pos, end - pos, "====\n");
                if (os_snprintf_error(end - pos, ret))