]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
RNR: Add data from neighbor database
authorJohn Crispin <john@phrozen.org>
Tue, 27 Jul 2021 23:42:20 +0000 (16:42 -0700)
committerJouni Malinen <j@w1.fi>
Mon, 8 Nov 2021 22:16:12 +0000 (00:16 +0200)
Include data from the existing neighbor database in the Reduced Neighbor
Report element in Beacon frames if the configuration option 'rnr' is
enabled for the BSS.

Signed-off-by: John Crispin <john@phrozen.org>
Signed-off-by: Muna Sinada <msinada@codeaurora.org>
Co-developed-by: Aloka Dixit <alokad@codeaurora.org>
Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
src/ap/ieee802_11.c
src/ap/ieee802_11.h

index 71fbefc8e58046f37fd6280c0c9c110daaa2373d..52df06d299c3473449f66c1d2def6f822f48522e 100644 (file)
@@ -7071,4 +7071,129 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
        return eid;
 }
 
+
+static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
+                                   size_t *current_len)
+{
+       struct hostapd_neighbor_entry *nr;
+       size_t total_len = 0, len = *current_len;
+
+       dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
+                        list) {
+               if (!nr->nr || wpabuf_len(nr->nr) < 12)
+                       continue;
+
+               if (nr->short_ssid == hapd->conf->ssid.short_ssid)
+                       continue;
+
+               /* Start a new element */
+               if (!len ||
+                   len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
+                       len = RNR_HEADER_LEN;
+                       total_len += RNR_HEADER_LEN;
+               }
+
+               len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
+               total_len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
+       }
+
+       *current_len = len;
+       return total_len;
+}
+
+
+size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
+{
+       size_t total_len = 0, current_len = 0;
+
+       switch (type) {
+       case WLAN_FC_STYPE_BEACON:
+               if (hapd->conf->rnr)
+                       total_len += hostapd_eid_nr_db_len(hapd, &current_len);
+               break;
+
+       default:
+               break;
+       }
+
+       return total_len;
+}
+
+
+static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
+                             size_t *current_len)
+{
+       struct hostapd_neighbor_entry *nr;
+       size_t len = *current_len;
+       u8 *size_offset = (eid - len) + 1;
+
+       dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
+                        list) {
+               if (!nr->nr || wpabuf_len(nr->nr) < 12)
+                       continue;
+
+               if (nr->short_ssid == hapd->conf->ssid.short_ssid)
+                       continue;
+
+               /* Start a new element */
+               if (!len ||
+                   len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
+                       *eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
+                       size_offset = eid++;
+                       len = RNR_HEADER_LEN;
+               }
+
+               /* TBTT Information Header subfield (2 octets) */
+               *eid++ = 0;
+               /* TBTT Information Length */
+               *eid++ = RNR_TBTT_INFO_LEN;
+               /* Operating Class */
+               *eid++ = wpabuf_head_u8(nr->nr)[10];
+               /* Channel Number */
+               *eid++ = wpabuf_head_u8(nr->nr)[11];
+               len += RNR_TBTT_HEADER_LEN;
+               /* TBTT Information Set */
+               /* TBTT Information field */
+               /* Neighbor AP TBTT Offset */
+               *eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
+               /* BSSID */
+               os_memcpy(eid, nr->bssid, ETH_ALEN);
+               eid += ETH_ALEN;
+               /* Short SSID */
+               os_memcpy(eid, &nr->short_ssid, 4);
+               eid += 4;
+               /* BSS parameters */
+               *eid++ = nr->bss_parameters;
+               /* 20 MHz PSD */
+               *eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
+               len += RNR_TBTT_INFO_LEN;
+               *size_offset = (eid - size_offset) - 1;
+       }
+
+       *current_len = len;
+       return eid;
+}
+
+
+u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
+{
+       u8 *eid_start = eid;
+       size_t current_len = 0;
+
+       switch (type) {
+       case WLAN_FC_STYPE_BEACON:
+               if (hapd->conf->rnr)
+                       eid = hostapd_eid_nr_db(hapd, eid, &current_len);
+               break;
+
+       default:
+               return eid_start;
+       }
+
+       if (eid == eid_start + 2)
+               return eid_start;
+
+       return eid;
+}
+
 #endif /* CONFIG_NATIVE_WINDOWS */
index ea8c60846936a7ebaffcea54db660457f7ec69a8..c59ad5e38e920210bdcb47d755e7873fce60a0f2 100644 (file)
@@ -194,5 +194,7 @@ int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth,
 
 void auth_sae_process_commit(void *eloop_ctx, void *user_ctx);
 u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len);
+size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type);
+u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type);
 
 #endif /* IEEE802_11_H */