diff --git a/hostapd/config_file.c b/hostapd/config_file.c index d80fb0821..091437a3b 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -3794,6 +3794,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, os_memcpy(bss->owe_transition_ssid, str, slen); bss->owe_transition_ssid_len = slen; os_free(str); + } else if (os_strcmp(buf, "owe_transition_ifname") == 0) { + os_strlcpy(bss->owe_transition_ifname, pos, + sizeof(bss->owe_transition_ifname)); + #endif /* CONFIG_OWE */ } else { wpa_printf(MSG_ERROR, diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 2c5fa7cb0..f0e553ca1 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1412,6 +1412,9 @@ own_ip_addr=127.0.0.1 #owe_transition_bssid= # SSID in same format as ssid2 described above. #owe_transition_ssid= +# Alternatively, OWE transition mode BSSID/SSID can be configured with a +# reference to a BSS operated by this hostapd process. +#owe_transition_ifname= # DHCP server for FILS HLP # If configured, hostapd will act as a DHCP relay for all FILS HLP requests diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 02164e16e..83f422964 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -649,6 +649,7 @@ struct hostapd_bss_config { macaddr owe_transition_bssid; u8 owe_transition_ssid[SSID_MAX_LEN]; size_t owe_transition_ssid_len; + char owe_transition_ifname[IFNAMSIZ + 1]; #endif /* CONFIG_OWE */ }; diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 542575829..3ea28a76e 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -391,6 +391,10 @@ static u8 * hostapd_eid_owe_trans(struct hostapd_data *hapd, u8 *eid, u8 *pos = eid; size_t elen; + if (hapd->conf->owe_transition_ifname[0] && + !hostapd_eid_owe_trans_enabled(hapd)) + hostapd_owe_trans_get_info(hapd); + if (!hostapd_eid_owe_trans_enabled(hapd)) return pos; diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 270e818d9..3ab2e0cee 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1680,6 +1680,108 @@ static void hostapd_set_own_neighbor_report(struct hostapd_data *hapd) } +#ifdef CONFIG_OWE + +static int hostapd_owe_iface_iter(struct hostapd_iface *iface, void *ctx) +{ + struct hostapd_data *hapd = ctx; + size_t i; + + for (i = 0; i < iface->num_bss; i++) { + struct hostapd_data *bss = iface->bss[i]; + + if (os_strcmp(hapd->conf->owe_transition_ifname, + bss->conf->iface) != 0) + continue; + + wpa_printf(MSG_DEBUG, + "OWE: ifname=%s found transition mode ifname=%s BSSID " + MACSTR " SSID %s", + hapd->conf->iface, bss->conf->iface, + MAC2STR(bss->own_addr), + wpa_ssid_txt(bss->conf->ssid.ssid, + bss->conf->ssid.ssid_len)); + if (!bss->conf->ssid.ssid_set || !bss->conf->ssid.ssid_len || + is_zero_ether_addr(bss->own_addr)) + continue; + + os_memcpy(hapd->conf->owe_transition_bssid, bss->own_addr, + ETH_ALEN); + os_memcpy(hapd->conf->owe_transition_ssid, + bss->conf->ssid.ssid, bss->conf->ssid.ssid_len); + hapd->conf->owe_transition_ssid_len = bss->conf->ssid.ssid_len; + wpa_printf(MSG_DEBUG, + "OWE: Copied transition mode information"); + return 1; + } + + return 0; +} + + +int hostapd_owe_trans_get_info(struct hostapd_data *hapd) +{ + if (hapd->conf->owe_transition_ssid_len > 0 && + !is_zero_ether_addr(hapd->conf->owe_transition_bssid)) + return 0; + + /* Find transition mode SSID/BSSID information from a BSS operated by + * this hostapd instance. */ + if (!hapd->iface->interfaces || + !hapd->iface->interfaces->for_each_interface) + return hostapd_owe_iface_iter(hapd->iface, hapd); + else + return hapd->iface->interfaces->for_each_interface( + hapd->iface->interfaces, hostapd_owe_iface_iter, hapd); +} + + +static int hostapd_owe_iface_iter2(struct hostapd_iface *iface, void *ctx) +{ + size_t i; + + for (i = 0; i < iface->num_bss; i++) { + struct hostapd_data *bss = iface->bss[i]; + int res; + + wpa_printf(MSG_DEBUG, "JKM:%s:iface=%s trans_ifname=%s", + __func__, bss->conf->iface, + bss->conf->owe_transition_ifname); + if (!bss->conf->owe_transition_ifname[0]) + continue; + res = hostapd_owe_trans_get_info(bss); + wpa_printf(MSG_DEBUG, "JKM:%s:iface=%s trans_ifname=%s res=%d", + __func__, bss->conf->iface, + bss->conf->owe_transition_ifname, res); + if (res == 0) + continue; + wpa_printf(MSG_DEBUG, + "OWE: Matching transition mode interface enabled - update beacon data for %s", + bss->conf->iface); + ieee802_11_set_beacon(bss); + } + + return 0; +} + +#endif /* CONFIG_OWE */ + + +static void hostapd_owe_update_trans(struct hostapd_iface *iface) +{ +#ifdef CONFIG_OWE + /* Check whether the enabled BSS can complete OWE transition mode + * configuration for any pending interface. */ + if (!iface->interfaces || + !iface->interfaces->for_each_interface) + hostapd_owe_iface_iter2(iface, NULL); + else + iface->interfaces->for_each_interface( + iface->interfaces, hostapd_owe_iface_iter2, NULL); +#endif /* CONFIG_OWE */ +} + + static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface, int err) { @@ -1855,6 +1957,7 @@ dfs_offload: #endif /* CONFIG_FST */ hostapd_set_state(iface, HAPD_IFACE_ENABLED); + hostapd_owe_update_trans(iface); wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED); if (hapd->setup_complete_cb) hapd->setup_complete_cb(hapd->setup_complete_cb_ctx); @@ -2646,6 +2749,7 @@ int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) return -1; } } + hostapd_owe_update_trans(hapd_iface); return 0; } diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 97e116571..fee413469 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -545,6 +545,7 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface, const struct hostapd_freq_params *freq_params); void hostapd_cleanup_cs_params(struct hostapd_data *hapd); void hostapd_periodic_iface(struct hostapd_iface *iface); +int hostapd_owe_trans_get_info(struct hostapd_data *hapd); /* utils.c */ int hostapd_register_probereq_cb(struct hostapd_data *hapd,