[wpa_supplicant] cumilative patch from commit d3ed34ba
Bug: 289287296
Test: Connect to open, WPA2, WPA3 and passpoint network
Test: Establish P2P connection
Test: Basic SoftAp tests
Test: Regression test (b/289297084)
BYPASS_INCLUSIVE_LANGUAGE_REASON=Merged from open source
d3ed34bac Define a QCA vendor command to configure MLO link id for TDLS
8e16372cf Indicate link reconfiguration with QCA vendor interface
7b9070229 Indicate TID to link mapping changes with QCA vendor interface
4120f9d7a PASN: Introduce configuration option to allow/deny PASN-UNAUTH
fc681995c Increase MAX_NL80211_NOISE_FREQS in survey dump handler for 6 GHz
df2f22faf MLD STA: Use AP MLD address as previous BSSID for reassociation requests
199b44213 MLD STA: Allow auth frames without ML IE for failure status codes
57386a647 Add QCA vendor command to indicate STA MLD setup links removal
527cf095f Add QCA vendor command to notify TID-to-Link mapping changes
a1601aaa6 WPS: Fix multi-ap fronthaul association
288566031 Store pmk_r1_name derived with wpa_ft_local_derive_pmk_r1() properly
e978072ba Do prune_association only after the STA is authorized
a2c09eb95 Define a QCA vendor attribute to update the CTS channel width
e49c3df63 Add a new driver feature flag for enhanced audio experience over WLAN
cc8a09a48 Add vendor attributes for forcing MLO power save and STR TX
c0e12a518 Add vendor attributes for EHT OM control, EMLSR padding delay
386d59e00 Do not disconnect EAPOL-Logoff before authentication
733723220 wpa_supplicant: Skip scan before starting a BSS in AP mode
f45cf609c wpa_supplicant: Fix compiling without IEEE8021X_EAPOL
c62e94d79 Add missing driver entries to wpa_supplicant documentation
9122b60ff DPP: Remove argument requirement for DPP push button command
397d432f6 Add vendor attributes for MLO link active, EMLSR entry/exit
5d285040d Rename VHT elements to match the standard
8f8f68ba6 hostapd: Support channel switch to 320 MHz channels
4d0743d5e Fix file mode bits
d930211bd Select 6 GHz mode correctly for ACS cases
927dbfb45 Fix 40 MHz channel bringup with ACS on the 6 GHz band
8bc84fcee Allow MLO disabled connection to legacy open/WPA2-Personal-only AP MLDs
b9c3b57a9 Update AP RSNE/RSNXE to RSN state machine on driver-selected BSS cases
566ab39a7 tests: KDK derivation based on Secure LTF capability
6972b0fa2 OWE: Update transition mode information on selecting a new BSS
f54ce7433 Fix determining mode for 6 GHz band when using hw_mode=any
5b568b21a Add support to fetch link layer stats per MLO link
6422b0d72 Fix vendor attribute numbering and relocate attribute accordingly
c858a6360 Add a vendor specific roam status of background scan abort
b171c5e4d Update QCA LL_STATS vendor command
6002fe87d SAE: Fix expected AP MLD address info in a debug print
c70405cef MLD STA: Do not fail on unknown IEs in Authentication frames
f8931fcba hostapd: Restore the flow of set beacon and WPA key init
e8912452e Export wpa_supplicant config item 'he' for external configuration
9932ff30c Allowed frequency list configuration for AP operation
07a7bcd7e WMM: Advertise support for 16 PTKSA replay counters for non-AP STA
ac54b6127 nl80211: Support for RNR elements
5d06acefd RNR: Add elements by default for EMA AP
8f1d38419 RNR: Skip interfaces on the same radio for MBSSID
921f82cf1 Sync with wireless-next.git include/uapi/linux/nl80211.h
302d761a8 Add QCA vendor feature flag for allowed frequency list
44c38af04 Add QCA vendor interface to get connected channels utilization
bb4560252 Add QCA vendor attribute to configure list of allowed frequencies for AP
Change-Id: Ibb944a0a4fbb2ac4abdec8fb09ce2dab3b551c27
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index b5fcc38..c3ee506 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -169,6 +169,7 @@
#ifdef CONFIG_PASN
/* comeback after 10 TUs */
bss->pasn_comeback_after = 10;
+ bss->pasn_noauth = 1;
#endif /* CONFIG_PASN */
}
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 07ee31c..def5fd5 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -906,6 +906,9 @@
#endif /* CONFIG_MACSEC */
#ifdef CONFIG_PASN
+ /* Whether to allow PASN-UNAUTH */
+ int pasn_noauth;
+
#ifdef CONFIG_TESTING_OPTIONS
/*
* Normally, KDK should be derived if and only if both sides support
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index f77f738..aa4dbe9 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -883,10 +883,10 @@
}
-static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
- struct hostapd_hw_modes *mode,
- int acs_ch_list_all,
- int **freq_list)
+void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
+ struct hostapd_hw_modes *mode,
+ int acs_ch_list_all, bool allow_disabled,
+ int **freq_list)
{
int i;
@@ -912,7 +912,7 @@
(!hapd->iface->conf->ieee80211ax &&
!hapd->iface->conf->ieee80211be)))
continue;
- if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
+ if ((!(chan->flag & HOSTAPD_CHAN_DISABLED) || allow_disabled) &&
!(hapd->iface->conf->acs_exclude_dfs &&
(chan->flag & HOSTAPD_CHAN_RADAR)) &&
!(chan->max_tx_power < hapd->iface->conf->min_tx_power))
@@ -969,7 +969,7 @@
selected_mode != mode->mode)
continue;
hostapd_get_hw_mode_any_channels(hapd, mode, acs_ch_list_all,
- &freq_list);
+ false, &freq_list);
}
params.freq_list = freq_list;
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 93b2244..023cbf1 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -156,6 +156,11 @@
void hostapd_get_ext_capa(struct hostapd_iface *iface);
+void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
+ struct hostapd_hw_modes *mode,
+ int acs_ch_list_all, bool allow_disabled,
+ int **freq_list);
+
static inline int hostapd_drv_set_countermeasures(struct hostapd_data *hapd,
int enabled)
{
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index c25a5bb..de944fe 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -468,8 +468,9 @@
{
struct hostapd_iface *iface = hapd->iface;
struct hostapd_data *tx_bss;
- size_t len;
+ size_t len, rnr_len = 0;
u8 elem_count = 0, *elem = NULL, **elem_offset = NULL, *end;
+ u8 rnr_elem_count = 0, *rnr_elem = NULL, **rnr_elem_offset = NULL;
if (!iface->mbssid_max_interfaces ||
iface->num_bss > iface->mbssid_max_interfaces ||
@@ -479,7 +480,7 @@
tx_bss = hostapd_mbssid_get_tx_bss(hapd);
len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count,
- NULL, 0);
+ NULL, 0, &rnr_len);
if (!len || (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED &&
elem_count > iface->ema_max_periodicity))
goto fail;
@@ -492,8 +493,19 @@
if (!elem_offset)
goto fail;
+ if (rnr_len) {
+ rnr_elem = os_zalloc(rnr_len);
+ if (!rnr_elem)
+ goto fail;
+
+ rnr_elem_offset = os_calloc(elem_count + 1, sizeof(u8 *));
+ if (!rnr_elem_offset)
+ goto fail;
+ }
+
end = hostapd_eid_mbssid(tx_bss, elem, elem + len, WLAN_FC_STYPE_BEACON,
- elem_count, elem_offset, NULL, 0);
+ elem_count, elem_offset, NULL, 0, rnr_elem,
+ &rnr_elem_count, rnr_elem_offset, rnr_len);
params->mbssid_tx_iface = tx_bss->conf->iface;
params->mbssid_index = hostapd_mbssid_get_bss_index(hapd);
@@ -501,12 +513,19 @@
params->mbssid_elem_len = end - elem;
params->mbssid_elem_count = elem_count;
params->mbssid_elem_offset = elem_offset;
+ params->rnr_elem = rnr_elem;
+ params->rnr_elem_len = rnr_len;
+ params->rnr_elem_count = rnr_elem_count;
+ params->rnr_elem_offset = rnr_elem_offset;
if (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED)
params->ema = true;
return 0;
fail:
+ os_free(rnr_elem);
+ os_free(rnr_elem_offset);
+ os_free(elem_offset);
os_free(elem);
wpa_printf(MSG_ERROR, "MBSSID: Configuration failed");
return -1;
@@ -590,7 +609,7 @@
#endif /* CONFIG_IEEE80211BE */
buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL,
- known_bss, known_bss_len);
+ known_bss, known_bss_len, NULL);
buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
buflen += hostapd_mbo_ie_len(hapd);
buflen += hostapd_eid_owe_trans_len(hapd);
@@ -658,7 +677,8 @@
pos = hostapd_get_rsne(hapd, pos, epos - pos);
pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
pos = hostapd_eid_mbssid(hapd, pos, epos, WLAN_FC_STYPE_PROBE_RESP, 0,
- NULL, known_bss, known_bss_len);
+ NULL, known_bss, known_bss_len, NULL, NULL,
+ NULL, 0);
pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
pos = hostapd_get_mde(hapd, pos, epos - pos);
@@ -2026,6 +2046,10 @@
params->mbssid_elem = NULL;
os_free(params->mbssid_elem_offset);
params->mbssid_elem_offset = NULL;
+ os_free(params->rnr_elem);
+ params->rnr_elem = NULL;
+ os_free(params->rnr_elem_offset);
+ params->rnr_elem_offset = NULL;
#ifdef CONFIG_FILS
os_free(params->fd_frame_tmpl);
params->fd_frame_tmpl = NULL;
@@ -2034,6 +2058,8 @@
os_free(params->unsol_bcast_probe_resp_tmpl);
params->unsol_bcast_probe_resp_tmpl = NULL;
#endif /* CONFIG_IEEE80211AX */
+ os_free(params->allowed_freqs);
+ params->allowed_freqs = NULL;
}
@@ -2045,7 +2071,8 @@
struct hostapd_config *iconf = iface->conf;
struct hostapd_hw_modes *cmode = iface->current_mode;
struct wpabuf *beacon, *proberesp, *assocresp;
- int res, ret = -1;
+ int res, ret = -1, i;
+ struct hostapd_hw_modes *mode;
if (!hapd->drv_priv) {
wpa_printf(MSG_ERROR, "Interface is disabled");
@@ -2120,6 +2147,19 @@
&cmode->eht_capab[IEEE80211_MODE_AP]) == 0)
params.freq = &freq;
+ for (i = 0; i < hapd->iface->num_hw_features; i++) {
+ mode = &hapd->iface->hw_features[i];
+
+ if (iconf->hw_mode != HOSTAPD_MODE_IEEE80211ANY &&
+ iconf->hw_mode != mode->mode)
+ continue;
+
+ hostapd_get_hw_mode_any_channels(hapd, mode,
+ !(iconf->acs_freq_list.num ||
+ iconf->acs_ch_list.num),
+ true, ¶ms.allowed_freqs);
+ }
+
res = hostapd_drv_set_ap(hapd, ¶ms);
hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
if (res)
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 8fc128e..510a06c 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -978,7 +978,8 @@
hapd->iconf->ch_switch_eht_config = 0;
if (width == CHAN_WIDTH_40 || width == CHAN_WIDTH_80 ||
- width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160)
+ width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160 ||
+ width == CHAN_WIDTH_320)
hapd->iconf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
else if (width == CHAN_WIDTH_20 || width == CHAN_WIDTH_20_NOHT)
hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 8b3fb40..112e6fa 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1476,11 +1476,11 @@
return -1;
}
- if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
+ if (start_beacon && hostapd_start_beacon(hapd, flush_old_stations) < 0)
return -1;
- if (start_beacon)
- return hostapd_start_beacon(hapd, flush_old_stations);
+ if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
+ return -1;
return 0;
}
@@ -1756,16 +1756,15 @@
static void hostapd_set_6ghz_sec_chan(struct hostapd_iface *iface)
{
- int bw, seg0;
+ int bw;
if (!is_6ghz_op_class(iface->conf->op_class))
return;
- seg0 = hostapd_get_oper_centr_freq_seg0_idx(iface->conf);
- bw = center_idx_to_bw_6ghz(seg0);
+ bw = op_class_to_bandwidth(iface->conf->op_class);
/* Assign the secondary channel if absent in config for
* bandwidths > 20 MHz */
- if (bw > 0 && !iface->conf->secondary_channel) {
+ if (bw >= 40 && !iface->conf->secondary_channel) {
if (((iface->conf->channel - 1) / 4) % 2)
iface->conf->secondary_channel = -1;
else
@@ -3340,7 +3339,6 @@
return;
}
- hostapd_prune_associations(hapd, sta->addr);
ap_sta_clear_disconnect_timeouts(hapd, sta);
sta->post_csa_sa_query = 0;
@@ -3602,6 +3600,7 @@
case 40:
case 80:
case 160:
+ case 320:
conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
break;
default:
@@ -3674,6 +3673,9 @@
case 160:
bandwidth = CONF_OPER_CHWIDTH_160MHZ;
break;
+ case 320:
+ bandwidth = CONF_OPER_CHWIDTH_320MHZ;
+ break;
default:
bandwidth = CONF_OPER_CHWIDTH_USE_HT;
break;
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 842d9f5..f836be4 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -1001,6 +1001,24 @@
}
+static bool skip_mode(struct hostapd_iface *iface,
+ struct hostapd_hw_modes *mode)
+{
+ int chan;
+
+ if (iface->freq > 0 && !hw_mode_get_channel(mode, iface->freq, &chan))
+ return true;
+
+ if (is_6ghz_op_class(iface->conf->op_class) && iface->freq == 0 &&
+ (mode->mode != HOSTAPD_MODE_IEEE80211A ||
+ mode->num_channels == 0 ||
+ !is_6ghz_freq(mode->channels[0].freq)))
+ return true;
+
+ return false;
+}
+
+
static void hostapd_determine_mode(struct hostapd_iface *iface)
{
int i;
@@ -1022,6 +1040,9 @@
mode = &iface->hw_features[i];
if (mode->mode == target_mode) {
+ if (skip_mode(iface, mode))
+ continue;
+
iface->current_mode = mode;
iface->conf->hw_mode = mode->mode;
break;
@@ -1152,11 +1173,9 @@
iface->current_mode = NULL;
for (i = 0; i < iface->num_hw_features; i++) {
struct hostapd_hw_modes *mode = &iface->hw_features[i];
- int chan;
if (mode->mode == iface->conf->hw_mode) {
- if (iface->freq > 0 &&
- !hw_mode_get_channel(mode, iface->freq, &chan))
+ if (skip_mode(iface, mode))
continue;
iface->current_mode = mode;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 0142ee4..93a6b4f 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2527,6 +2527,7 @@
pasn->cb_ctx = hapd;
pasn->send_mgmt = hapd_pasn_send_mlme;
pasn->pasn_groups = hapd->conf->pasn_groups;
+ pasn->noauth = hapd->conf->pasn_noauth;
pasn->wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
pasn->rsn_pairwise = hapd->conf->rsn_pairwise;
pasn->derive_kdk = hapd->iface->drv_flags2 &
@@ -3696,7 +3697,7 @@
if (resp != WLAN_STATUS_SUCCESS)
return resp;
- resp = set_sta_vht_opmode(hapd, sta, elems->vht_opmode_notif);
+ resp = set_sta_vht_opmode(hapd, sta, elems->opmode_notif);
if (resp != WLAN_STATUS_SUCCESS)
return resp;
}
@@ -5758,7 +5759,11 @@
sta->flags |= WLAN_STA_WDS;
}
- if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP)) {
+ /* WPS not supported on backhaul BSS. Disable 4addr mode on fronthaul */
+ if ((sta->flags & WLAN_STA_WDS) ||
+ (sta->flags & WLAN_STA_MULTI_AP &&
+ !(hapd->conf->multi_ap & FRONTHAUL_BSS) &&
+ !(sta->flags & WLAN_STA_WPS))) {
int ret;
char ifname_wds[IFNAMSIZ + 1];
@@ -6347,7 +6352,7 @@
!hapd->cs_freq_params.eht_enabled))
return eid;
- /* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80 */
+ /* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80, 4: 320 */
switch (hapd->cs_freq_params.bandwidth) {
case 40:
bw = 0;
@@ -6362,6 +6367,9 @@
case 160:
bw = 2;
break;
+ case 320:
+ bw = 4;
+ break;
default:
/* not valid VHT bandwidth or not in CSA */
return eid;
@@ -6379,9 +6387,9 @@
&chan2) != HOSTAPD_MODE_IEEE80211A)
return eid;
- *eid++ = WLAN_EID_VHT_CHANNEL_SWITCH_WRAPPER;
+ *eid++ = WLAN_EID_CHANNEL_SWITCH_WRAPPER;
*eid++ = 5; /* Length of Channel Switch Wrapper */
- *eid++ = WLAN_EID_VHT_WIDE_BW_CHSWITCH;
+ *eid++ = WLAN_EID_WIDE_BW_CHSWITCH;
*eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */
*eid++ = bw; /* New Channel Width */
*eid++ = chan1; /* New Channel Center Frequency Segment 0 */
@@ -6421,9 +6429,16 @@
}
-static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
- struct hostapd_data *reporting_hapd,
- size_t *current_len)
+struct mbssid_ie_profiles {
+ u8 start;
+ u8 end;
+};
+
+static size_t
+hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
+ struct hostapd_data *reporting_hapd,
+ size_t *current_len,
+ struct mbssid_ie_profiles *skip_profiles)
{
size_t total_len = 0, len = *current_len;
int tbtt_count = 0;
@@ -6449,6 +6464,10 @@
bss->conf->ignore_broadcast_ssid)
continue;
+ if (skip_profiles &&
+ i >= skip_profiles->start && i < skip_profiles->end)
+ continue;
+
if (len + RNR_TBTT_INFO_LEN > 255 ||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
break;
@@ -6527,7 +6546,7 @@
continue;
len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
- current_len);
+ current_len, NULL);
}
return len;
@@ -6550,15 +6569,18 @@
total_len += hostapd_eid_rnr_colocation_len(
hapd, ¤t_len);
- if (hapd->conf->rnr && hapd->iface->num_bss > 1)
+ if (hapd->conf->rnr && hapd->iface->num_bss > 1 &&
+ !hapd->iconf->mbssid)
total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
- ¤t_len);
+ ¤t_len,
+ NULL);
break;
case WLAN_FC_STYPE_ACTION:
if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
- ¤t_len);
+ ¤t_len,
+ NULL);
break;
default:
@@ -6626,7 +6648,8 @@
static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
struct hostapd_data *reporting_hapd,
- u8 *eid, size_t *current_len)
+ u8 *eid, size_t *current_len,
+ struct mbssid_ie_profiles *skip_profiles)
{
struct hostapd_data *bss;
struct hostapd_iface *iface = hapd->iface;
@@ -6671,6 +6694,10 @@
bss->conf->ignore_broadcast_ssid)
continue;
+ if (skip_profiles &&
+ i >= skip_profiles->start && i < skip_profiles->end)
+ continue;
+
if (len + RNR_TBTT_INFO_LEN > 255 ||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
break;
@@ -6687,7 +6714,7 @@
if (iface->conf->mbssid != MBSSID_DISABLED &&
iface->num_bss > 1) {
bss_param |= RNR_BSS_PARAM_MULTIPLE_BSSID;
- if (i == 0)
+ if (bss == hostapd_mbssid_get_tx_bss(hapd))
bss_param |=
RNR_BSS_PARAM_TRANSMITTED_BSSID;
}
@@ -6735,7 +6762,7 @@
continue;
eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
- current_len);
+ current_len, NULL);
}
return eid;
@@ -6759,15 +6786,16 @@
eid = hostapd_eid_rnr_colocation(hapd, eid,
¤t_len);
- if (hapd->conf->rnr && hapd->iface->num_bss > 1)
+ if (hapd->conf->rnr && hapd->iface->num_bss > 1 &&
+ !hapd->iconf->mbssid)
eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
- ¤t_len);
+ ¤t_len, NULL);
break;
case WLAN_FC_STYPE_ACTION:
if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
- ¤t_len);
+ ¤t_len, NULL);
break;
default:
@@ -6856,7 +6884,7 @@
size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
u8 *elem_count, const u8 *known_bss,
- size_t known_bss_len)
+ size_t known_bss_len, size_t *rnr_len)
{
size_t len = 0, bss_index = 1;
@@ -6875,13 +6903,29 @@
}
while (bss_index < hapd->iface->num_bss) {
+ size_t rnr_count = bss_index;
+
len += hostapd_eid_mbssid_elem_len(hapd, frame_type,
&bss_index, known_bss,
known_bss_len);
if (frame_type == WLAN_FC_STYPE_BEACON)
*elem_count += 1;
+ if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED && rnr_len) {
+ size_t rnr_cur_len = 0;
+ struct mbssid_ie_profiles skip_profiles = {
+ rnr_count, bss_index
+ };
+
+ *rnr_len += hostapd_eid_rnr_iface_len(
+ hapd, hostapd_mbssid_get_tx_bss(hapd),
+ &rnr_cur_len, &skip_profiles);
+ }
}
+
+ if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED && rnr_len)
+ *rnr_len += hostapd_eid_rnr_len(hapd, frame_type);
+
return len;
}
@@ -6993,10 +7037,12 @@
u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
unsigned int frame_stype, u8 elem_count,
u8 **elem_offset,
- const u8 *known_bss, size_t known_bss_len)
+ const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid,
+ u8 *rnr_count, u8 **rnr_offset, size_t rnr_len)
{
- size_t bss_index = 1;
- u8 elem_index = 0;
+ size_t bss_index = 1, cur_len = 0;
+ u8 elem_index = 0, *rnr_start_eid = rnr_eid;
+ bool add_rnr;
if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 ||
(frame_stype != WLAN_FC_STYPE_BEACON &&
@@ -7009,7 +7055,13 @@
return eid;
}
+ add_rnr = hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&
+ frame_stype == WLAN_FC_STYPE_BEACON &&
+ rnr_eid && rnr_count && rnr_offset && rnr_len;
+
while (bss_index < hapd->iface->num_bss) {
+ unsigned int rnr_start_count = bss_index;
+
if (frame_stype == WLAN_FC_STYPE_BEACON) {
if (elem_index == elem_count) {
wpa_printf(MSG_WARNING,
@@ -7024,6 +7076,31 @@
hostapd_max_bssid_indicator(hapd),
&bss_index, elem_count,
known_bss, known_bss_len);
+
+ if (add_rnr) {
+ struct mbssid_ie_profiles skip_profiles = {
+ rnr_start_count, bss_index
+ };
+
+ rnr_offset[*rnr_count] = rnr_eid;
+ *rnr_count = *rnr_count + 1;
+ cur_len = 0;
+ rnr_eid = hostapd_eid_rnr_iface(
+ hapd, hostapd_mbssid_get_tx_bss(hapd),
+ rnr_eid, &cur_len, &skip_profiles);
+ }
+ }
+
+ if (add_rnr && (size_t) (rnr_eid - rnr_start_eid) < rnr_len) {
+ rnr_offset[*rnr_count] = rnr_eid;
+ *rnr_count = *rnr_count + 1;
+ cur_len = 0;
+
+ if (hapd->conf->rnr)
+ rnr_eid = hostapd_eid_nr_db(hapd, rnr_eid, &cur_len);
+ if (get_colocation_mode(hapd) == COLOCATED_LOWER_BAND)
+ rnr_eid = hostapd_eid_rnr_colocation(hapd, rnr_eid,
+ &cur_len);
}
return eid;
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index 1e4c843..1190a5e 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -218,11 +218,12 @@
const u8 *eht_capab, size_t eht_capab_len);
size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
u8 *elem_count, const u8 *known_bss,
- size_t known_bss_len);
+ size_t known_bss_len, size_t *rnr_len);
u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
unsigned int frame_stype, u8 elem_count,
u8 **elem_offset,
- const u8 *known_bss, size_t known_bss_len);
+ const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid,
+ u8 *rnr_count, u8 **rnr_offset, size_t rnr_len);
void punct_update_legacy_bw(u16 bitmap, u8 pri_chan,
enum oper_chan_width *width, u8 *seg0, u8 *seg1);
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 46a47d0..8b67669 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -43,9 +43,9 @@
#ifdef CONFIG_HS20
static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx);
#endif /* CONFIG_HS20 */
-static void ieee802_1x_finished(struct hostapd_data *hapd,
+static bool ieee802_1x_finished(struct hostapd_data *hapd,
struct sta_info *sta, int success,
- int remediation);
+ int remediation, bool logoff);
static void ieee802_1x_send(struct hostapd_data *hapd, struct sta_info *sta,
@@ -2287,16 +2287,18 @@
}
-static void _ieee802_1x_finished(void *ctx, void *sta_ctx, int success,
- int preauth, int remediation)
+static bool _ieee802_1x_finished(void *ctx, void *sta_ctx, int success,
+ int preauth, int remediation, bool logoff)
{
struct hostapd_data *hapd = ctx;
struct sta_info *sta = sta_ctx;
- if (preauth)
+ if (preauth) {
rsn_preauth_finished(hapd, sta, success);
- else
- ieee802_1x_finished(hapd, sta, success, remediation);
+ return false;
+ }
+
+ return ieee802_1x_finished(hapd, sta, success, remediation, logoff);
}
@@ -2977,9 +2979,9 @@
#endif /* CONFIG_HS20 */
-static void ieee802_1x_finished(struct hostapd_data *hapd,
+static bool ieee802_1x_finished(struct hostapd_data *hapd,
struct sta_info *sta, int success,
- int remediation)
+ int remediation, bool logoff)
{
const u8 *key;
size_t len;
@@ -3039,6 +3041,11 @@
* EAP-FAST with anonymous provisioning, may require another
* EAPOL authentication to be started to complete connection.
*/
- ap_sta_delayed_1x_auth_fail_disconnect(hapd, sta);
+ ap_sta_delayed_1x_auth_fail_disconnect(hapd, sta,
+ logoff ? 0 : 10);
+ if (logoff && sta->wpa_sm)
+ return true;
}
+
+ return false;
}
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 63f514c..2fb6edf 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -197,7 +197,10 @@
ap_sta_set_authorized(hapd, sta, 0);
hostapd_set_sta_flags(hapd, sta);
- if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP))
+ if ((sta->flags & WLAN_STA_WDS) ||
+ (sta->flags & WLAN_STA_MULTI_AP &&
+ !(hapd->conf->multi_ap & FRONTHAUL_BSS) &&
+ !(sta->flags & WLAN_STA_WPS)))
hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
if (sta->ipaddr)
@@ -1280,10 +1283,12 @@
if (!!authorized == !!(sta->flags & WLAN_STA_AUTHORIZED))
return;
- if (authorized)
+ if (authorized) {
+ hostapd_prune_associations(hapd, sta->addr);
sta->flags |= WLAN_STA_AUTHORIZED;
- else
+ } else {
sta->flags &= ~WLAN_STA_AUTHORIZED;
+ }
#ifdef CONFIG_P2P
if (hapd->p2p_group == NULL) {
@@ -1536,11 +1541,12 @@
void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
- struct sta_info *sta)
+ struct sta_info *sta,
+ unsigned timeout)
{
wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
"IEEE 802.1X: Force disconnection of " MACSTR
- " after EAP-Failure in 10 ms", MAC2STR(sta->addr));
+ " after EAP-Failure in %u ms", MAC2STR(sta->addr), timeout);
/*
* Add a small sleep to increase likelihood of previously requested
@@ -1548,8 +1554,8 @@
* operations.
*/
eloop_cancel_timeout(ap_sta_delayed_1x_auth_fail_cb, hapd, sta);
- eloop_register_timeout(0, 10000, ap_sta_delayed_1x_auth_fail_cb,
- hapd, sta);
+ eloop_register_timeout(0, timeout * 1000,
+ ap_sta_delayed_1x_auth_fail_cb, hapd, sta);
}
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index b59b758..8433ff8 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -373,7 +373,8 @@
int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen);
void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
- struct sta_info *sta);
+ struct sta_info *sta,
+ unsigned timeout);
int ap_sta_pending_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
struct sta_info *sta);
int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta);
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index 35585cd..2402ad9 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -3085,7 +3085,7 @@
struct wpa_state_machine *sm,
const u8 *r0kh_id, size_t r0kh_id_len,
const u8 *req_pmk_r0_name,
- const u8 *req_pmk_r1_name,
+ u8 *out_pmk_r1_name,
u8 *out_pmk_r1, int *out_pairwise,
struct vlan_description *vlan,
const u8 **identity, size_t *identity_len,
@@ -3096,7 +3096,6 @@
{
struct wpa_auth_config *conf = &wpa_auth->conf;
const struct wpa_ft_pmk_r0_sa *r0;
- u8 pmk_r1_name[WPA_PMK_NAME_LEN];
int expires_in = 0;
int session_timeout = 0;
struct os_reltime now;
@@ -3115,7 +3114,7 @@
if (wpa_derive_pmk_r1(r0->pmk_r0, r0->pmk_r0_len, r0->pmk_r0_name,
conf->r1_key_holder,
- sm->addr, out_pmk_r1, pmk_r1_name) < 0)
+ sm->addr, out_pmk_r1, out_pmk_r1_name) < 0)
return -1;
os_get_reltime(&now);
@@ -3126,7 +3125,7 @@
session_timeout = r0->session_timeout - now.sec;
wpa_ft_store_pmk_r1(wpa_auth, sm->addr, out_pmk_r1, r0->pmk_r0_len,
- pmk_r1_name,
+ out_pmk_r1_name,
sm->pairwise, r0->vlan, expires_in, session_timeout,
r0->identity, r0->identity_len,
r0->radius_cui, r0->radius_cui_len);