hostapd: Extend the configuration of RRM capabilities
[mech_eap.git] / src / ap / ieee802_11.c
index 3ac225d..dd3d04d 100644 (file)
@@ -140,6 +140,7 @@ u16 hostapd_own_capab_info(struct hostapd_data *hapd)
        int capab = WLAN_CAPABILITY_ESS;
        int privacy;
        int dfs;
+       int i;
 
        /* Check if any of configured channels require DFS */
        dfs = hostapd_is_dfs_required(hapd->iface);
@@ -187,8 +188,12 @@ u16 hostapd_own_capab_info(struct hostapd_data *hapd)
            (hapd->iconf->spectrum_mgmt_required || dfs))
                capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
 
-       if (hapd->conf->radio_measurements)
-               capab |= IEEE80211_CAP_RRM;
+       for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
+               if (hapd->conf->radio_measurements[i]) {
+                       capab |= IEEE80211_CAP_RRM;
+                       break;
+               }
+       }
 
        return capab;
 }
@@ -554,6 +559,18 @@ static void sae_set_retransmit_timer(struct hostapd_data *hapd,
 }
 
 
+void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
+{
+       sta->flags |= WLAN_STA_AUTH;
+       sta->auth_alg = WLAN_AUTH_SAE;
+       mlme_authenticate_indication(hapd, sta);
+       wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
+       sta->sae->state = SAE_ACCEPTED;
+       wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
+                              sta->sae->pmk, sta->sae->pmkid);
+}
+
+
 static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
                       const u8 *bssid, u8 auth_transaction)
 {
@@ -676,13 +693,7 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
 
                        sae_set_retransmit_timer(hapd, sta);
                } else {
-                       sta->flags |= WLAN_STA_AUTH;
-                       sta->auth_alg = WLAN_AUTH_SAE;
-                       mlme_authenticate_indication(hapd, sta);
-                       wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
-                       sta->sae->state = SAE_ACCEPTED;
-                       wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
-                                              sta->sae->pmk, sta->sae->pmkid);
+                       sae_accept_sta(hapd, sta);
                }
                break;
        case SAE_ACCEPTED:
@@ -691,6 +702,7 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
                                   ") doing reauthentication",
                                   MAC2STR(sta->addr));
                        ap_free_sta(hapd, sta);
+                       wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
                } else {
                        if (sae_check_big_sync(sta))
                                return WLAN_STATUS_SUCCESS;
@@ -733,6 +745,13 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
                sta->sae->sync = 0;
        }
 
+       if (sta->mesh_sae_pmksa_caching) {
+               wpa_printf(MSG_DEBUG,
+                          "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
+               wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
+               sta->mesh_sae_pmksa_caching = 0;
+       }
+
        if (auth_transaction == 1) {
                const u8 *token = NULL, *pos, *end;
                size_t token_len = 0;
@@ -1207,7 +1226,7 @@ static void handle_auth(struct hostapd_data *hapd,
                                WLAN_STA_AUTHORIZED);
 
                if (hostapd_sta_add(hapd, sta->addr, 0, 0, 0, 0, 0,
-                                   NULL, NULL, sta->flags, 0, 0, 0)) {
+                                   NULL, NULL, sta->flags, 0, 0, 0, 0)) {
                        hostapd_logger(hapd, sta->addr,
                                       HOSTAPD_MODULE_IEEE80211,
                                       HOSTAPD_LEVEL_NOTICE,
@@ -1714,8 +1733,21 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
                sta->mb_ies = NULL;
 #endif /* CONFIG_FST */
 
+#ifdef CONFIG_MBO
        mbo_ap_check_sta_assoc(hapd, sta, &elems);
 
+       if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
+           elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
+           hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
+               wpa_printf(MSG_INFO,
+                          "MBO: Reject WPA2 association without PMF");
+               return WLAN_STATUS_UNSPECIFIED_FAILURE;
+       }
+#endif /* CONFIG_MBO */
+
+       ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
+                                   elems.supp_op_classes_len);
+
        return WLAN_STATUS_SUCCESS;
 }
 
@@ -1778,7 +1810,8 @@ static int add_associated_sta(struct hostapd_data *hapd,
                            sta->flags & WLAN_STA_HT ? &ht_cap : NULL,
                            sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
                            sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
-                           sta->vht_opmode, sta->added_unassoc)) {
+                           sta->vht_opmode, sta->p2p_ie ? 1 : 0,
+                           sta->added_unassoc)) {
                hostapd_logger(hapd, sta->addr,
                               HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
                               "Could not %s STA to kernel driver",
@@ -2769,6 +2802,25 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
                wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
        hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
        ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
+
+       if (sta->pending_eapol_rx) {
+               struct os_reltime now, age;
+
+               os_get_reltime(&now);
+               os_reltime_sub(&now, &sta->pending_eapol_rx->rx_time, &age);
+               if (age.sec == 0 && age.usec < 200000) {
+                       wpa_printf(MSG_DEBUG,
+                                  "Process pending EAPOL frame that was received from " MACSTR " just before association notification",
+                                  MAC2STR(sta->addr));
+                       ieee802_1x_receive(
+                               hapd, mgmt->da,
+                               wpabuf_head(sta->pending_eapol_rx->buf),
+                               wpabuf_len(sta->pending_eapol_rx->buf));
+               }
+               wpabuf_free(sta->pending_eapol_rx->buf);
+               os_free(sta->pending_eapol_rx);
+               sta->pending_eapol_rx = NULL;
+       }
 }
 
 
@@ -2857,7 +2909,7 @@ void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
                handle_assoc_cb(hapd, mgmt, len, 1, ok);
                break;
        case WLAN_FC_STYPE_PROBE_RESP:
-               wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb");
+               wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb ok=%d", ok);
                break;
        case WLAN_FC_STYPE_DEAUTH:
                wpa_printf(MSG_DEBUG, "mgmt::deauth cb");
@@ -2868,7 +2920,7 @@ void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
                handle_disassoc_cb(hapd, mgmt, len, ok);
                break;
        case WLAN_FC_STYPE_ACTION:
-               wpa_printf(MSG_DEBUG, "mgmt::action cb");
+               wpa_printf(MSG_DEBUG, "mgmt::action cb ok=%d", ok);
                break;
        default:
                wpa_printf(MSG_INFO, "unknown mgmt cb frame subtype %d", stype);
@@ -2966,6 +3018,8 @@ void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr)
        }
        if (sta == NULL)
                return;
+       wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POLL_OK MACSTR,
+               MAC2STR(sta->addr));
        if (!(sta->flags & WLAN_STA_PENDING_POLL))
                return;