--- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -168,9 +168,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm. ifdef CONFIG_UBUS CFLAGS += -DUBUS_SUPPORT -OBJS += ../src/utils/uloop.o OBJS += ../src/ap/ubus.o -LIBS += -lubox -lubus +LIBS += -lubus +NEED_ULOOP:=y +endif + +ifdef CONFIG_UCODE +CFLAGS += -DUCODE_SUPPORT +OBJS += ../src/utils/ucode.o +OBJS += ../src/ap/ucode.o +NEED_ULOOP:=y +endif + +ifdef NEED_ULOOP +OBJS += ../src/utils/uloop.o +LIBS += -lubox endif ifdef CONFIG_CODE_COVERAGE --- a/hostapd/main.c +++ b/hostapd/main.c @@ -898,6 +898,7 @@ int main(int argc, char *argv[]) } hostapd_global_ctrl_iface_init(&interfaces); + hostapd_ucode_init(&interfaces); if (hostapd_global_run(&interfaces, daemonize, pid_file)) { wpa_printf(MSG_ERROR, "Failed to start eloop"); @@ -907,6 +908,7 @@ int main(int argc, char *argv[]) ret = 0; out: + hostapd_ucode_free(); hostapd_global_ctrl_iface_deinit(&interfaces); /* Deinitialize all interfaces */ for (i = 0; i < interfaces.count; i++) { --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -18,6 +18,7 @@ #include "ap_config.h" #include "drivers/driver.h" #include "ubus.h" +#include "ucode.h" #define OCE_STA_CFON_ENABLED(hapd) \ ((hapd->conf->oce & OCE_STA_CFON) && \ @@ -50,6 +51,10 @@ struct hapd_interfaces { struct hostapd_config * (*config_read_cb)(const char *config_fname); int (*ctrl_iface_init)(struct hostapd_data *hapd); void (*ctrl_iface_deinit)(struct hostapd_data *hapd); + int (*ctrl_iface_recv)(struct hostapd_data *hapd, + char *buf, char *reply, int reply_size, + struct sockaddr_storage *from, + socklen_t fromlen); int (*for_each_interface)(struct hapd_interfaces *interfaces, int (*cb)(struct hostapd_iface *iface, void *ctx), void *ctx); @@ -171,6 +176,7 @@ struct hostapd_data { struct hostapd_config *iconf; struct hostapd_bss_config *conf; struct hostapd_ubus_bss ubus; + struct hostapd_ucode_bss ucode; int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; @@ -463,6 +469,7 @@ struct hostapd_sta_info { */ struct hostapd_iface { struct hapd_interfaces *interfaces; + struct hostapd_ucode_iface ucode; void *owner; char *config_fname; struct hostapd_config *conf; @@ -637,6 +644,8 @@ struct hostapd_iface * hostapd_init(stru struct hostapd_iface * hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, const char *config_fname, int debug); +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon); +void hostapd_bss_deinit(struct hostapd_data *hapd); void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, int reassoc); void hostapd_interface_deinit_free(struct hostapd_iface *iface); @@ -662,6 +671,7 @@ hostapd_switch_channel_fallback(struct h 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); +void hostapd_owe_update_trans(struct hostapd_iface *iface); void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); /* utils.c */ --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -216,6 +216,8 @@ int hostapd_reload_config(struct hostapd struct hostapd_config *newconf, *oldconf; size_t j; + hostapd_ucode_reload_bss(hapd); + if (iface->config_fname == NULL) { /* Only in-memory config in use - assume it has been updated */ hostapd_clear_old(iface); @@ -376,6 +378,7 @@ void hostapd_free_hapd_data(struct hosta hapd->beacon_set_done = 0; wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); + hostapd_ucode_free_bss(hapd); hostapd_ubus_free_bss(hapd); accounting_deinit(hapd); hostapd_deinit_wpa(hapd); @@ -531,6 +534,7 @@ void hostapd_cleanup_iface_partial(struc static void hostapd_cleanup_iface(struct hostapd_iface *iface) { wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); + hostapd_ucode_free_iface(iface); eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface, NULL); @@ -1104,7 +1108,7 @@ static int db_table_create_radius_attrib * initialized. Most of the modules that are initialized here will be * deinitialized in hostapd_cleanup(). */ -static int hostapd_setup_bss(struct hostapd_data *hapd, int first) +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool set_beacon) { struct hostapd_bss_config *conf = hapd->conf; u8 ssid[SSID_MAX_LEN + 1]; @@ -1400,6 +1404,7 @@ static int hostapd_setup_bss(struct host hapd->driver->set_operstate(hapd->drv_priv, 1); hostapd_ubus_add_bss(hapd); + hostapd_ucode_add_bss(hapd); return 0; } @@ -1945,7 +1950,7 @@ static int hostapd_owe_iface_iter2(struc #endif /* CONFIG_OWE */ -static void hostapd_owe_update_trans(struct hostapd_iface *iface) +void hostapd_owe_update_trans(struct hostapd_iface *iface) { #ifdef CONFIG_OWE /* Check whether the enabled BSS can complete OWE transition mode @@ -2090,7 +2095,7 @@ static int hostapd_setup_interface_compl hapd = iface->bss[j]; if (j) os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); - if (hostapd_setup_bss(hapd, j == 0)) { + if (hostapd_setup_bss(hapd, j == 0, true)) { for (;;) { hapd = iface->bss[j]; hostapd_bss_deinit_no_free(hapd); @@ -2368,7 +2373,7 @@ hostapd_alloc_bss_data(struct hostapd_if } -static void hostapd_bss_deinit(struct hostapd_data *hapd) +void hostapd_bss_deinit(struct hostapd_data *hapd) { if (!hapd) return; @@ -2985,7 +2990,7 @@ int hostapd_add_iface(struct hapd_interf if (start_ctrl_iface_bss(hapd) < 0 || (hapd_iface->state == HAPD_IFACE_ENABLED && - hostapd_setup_bss(hapd, -1))) { + hostapd_setup_bss(hapd, -1, true))) { hostapd_cleanup(hapd); hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; hapd_iface->conf->num_bss--; @@ -3137,7 +3142,8 @@ int hostapd_remove_iface(struct hapd_int hapd_iface = interfaces->iface[i]; if (hapd_iface == NULL) return -1; - if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { + if (!os_strcmp(hapd_iface->phy, buf) || + !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { wpa_printf(MSG_INFO, "Remove interface '%s'", buf); hapd_iface->driver_ap_teardown = !!(hapd_iface->drv_flags & --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -172,8 +172,20 @@ endif ifdef CONFIG_UBUS CFLAGS += -DUBUS_SUPPORT OBJS += ubus.o +LIBS += -lubus +NEED_ULOOP:=y +endif + +ifdef CONFIG_UCODE +CFLAGS += -DUCODE_SUPPORT +OBJS += ../src/utils/ucode.o +OBJS += ucode.o +NEED_ULOOP:=y +endif + +ifdef NEED_ULOOP OBJS += ../src/utils/uloop.o -LIBS += -lubox -lubus +LIBS += -lubox endif ifdef CONFIG_CODE_COVERAGE @@ -956,6 +968,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o ifdef CONFIG_UBUS OBJS += ../src/ap/ubus.o endif +ifdef CONFIG_UCODE +OBJS += ../src/ap/ucode.o +endif endif CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1025,6 +1025,7 @@ void wpa_supplicant_set_state(struct wpa sme_sched_obss_scan(wpa_s, 0); } wpa_s->wpa_state = state; + wpas_ucode_update_state(wpa_s); #ifdef CONFIG_BGSCAN if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) @@ -6944,6 +6945,7 @@ struct wpa_supplicant * wpa_supplicant_a #endif /* CONFIG_P2P */ wpas_ubus_add_bss(wpa_s); + wpas_ucode_add_bss(wpa_s); return wpa_s; } @@ -6971,6 +6973,7 @@ int wpa_supplicant_remove_iface(struct w struct wpa_supplicant *parent = wpa_s->parent; #endif /* CONFIG_MESH */ + wpas_ucode_free_bss(wpa_s); wpas_ubus_free_bss(wpa_s); /* Remove interface from the global list of interfaces */ @@ -7238,6 +7241,7 @@ struct wpa_global * wpa_supplicant_init( eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, wpas_periodic, global, NULL); + wpas_ucode_init(global); return global; } @@ -7276,12 +7280,8 @@ int wpa_supplicant_run(struct wpa_global eloop_register_signal_terminate(wpa_supplicant_terminate, global); eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); - wpas_ubus_add(global); - eloop_run(); - wpas_ubus_free(global); - return 0; } @@ -7314,6 +7314,8 @@ void wpa_supplicant_deinit(struct wpa_gl wpas_notify_supplicant_deinitialized(global); + wpas_ucode_free(); + eap_peer_unregister_methods(); #ifdef CONFIG_AP eap_server_unregister_methods(); --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -20,6 +20,7 @@ #include "config_ssid.h" #include "wmm_ac.h" #include "ubus.h" +#include "ucode.h" extern const char *const wpa_supplicant_version; extern const char *const wpa_supplicant_license; @@ -600,6 +601,7 @@ struct wpa_supplicant { unsigned char perm_addr[ETH_ALEN]; char ifname[100]; struct wpas_ubus_bss ubus; + struct wpas_ucode_bss ucode; #ifdef CONFIG_MATCH_IFACE int matched; #endif /* CONFIG_MATCH_IFACE */ --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -4877,6 +4877,7 @@ try_again: return -1; } + interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb); return 0; @@ -4978,6 +4979,7 @@ fail: os_free(fname); interface->global_ctrl_sock = s; + interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive, interface, NULL); --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -3357,6 +3357,25 @@ struct wpa_driver_ops { const char *ifname); /** + * if_rename - Rename a virtual interface + * @priv: Private driver interface data + * @type: Interface type + * @ifname: Interface name of the virtual interface to be renamed + * (NULL when renaming the AP BSS interface) + * @new_name: New interface name of the virtual interface + * Returns: 0 on success, -1 on failure + */ + int (*if_rename)(void *priv, enum wpa_driver_if_type type, + const char *ifname, const char *new_name); + + /** + * set_first_bss - Make a virtual interface the first (primary) bss + * @priv: Private driver interface data + * Returns: 0 on success, -1 on failure + */ + int (*set_first_bss)(void *priv); + + /** * set_sta_vlan - Bind a station into a specific interface (AP only) * @priv: Private driver interface data * @ifname: Interface (main or virtual BSS or VLAN) @@ -5827,6 +5846,7 @@ union wpa_event_data { /** * struct ch_switch + * @count: Count until channel switch activates * @freq: Frequency of new channel in MHz * @ht_enabled: Whether this is an HT channel * @ch_offset: Secondary channel offset @@ -5835,6 +5855,7 @@ union wpa_event_data { * @cf2: Center frequency 2 */ struct ch_switch { + int count; int freq; int ht_enabled; int ch_offset; --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -655,6 +655,7 @@ static void mlme_event_ch_switch(struct struct nlattr *ifindex, struct nlattr *freq, struct nlattr *type, struct nlattr *bw, struct nlattr *cf1, struct nlattr *cf2, + struct nlattr *count, int finished) { struct i802_bss *bss; @@ -714,6 +715,8 @@ static void mlme_event_ch_switch(struct data.ch_switch.cf1 = nla_get_u32(cf1); if (cf2) data.ch_switch.cf2 = nla_get_u32(cf2); + if (count) + data.ch_switch.count = nla_get_u32(count); if (finished) bss->freq = data.ch_switch.freq; @@ -2886,6 +2889,7 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CHANNEL_WIDTH], tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], + tb[NL80211_ATTR_CH_SWITCH_COUNT], 0); break; case NL80211_CMD_CH_SWITCH_NOTIFY: @@ -2896,6 +2900,7 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CHANNEL_WIDTH], tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], + NULL, 1); break; case NL80211_CMD_DISCONNECT: --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -4702,6 +4702,7 @@ void supplicant_event(void *ctx, enum wp event_to_string(event), event); #endif /* CONFIG_NO_STDOUT_DEBUG */ + wpas_ucode_event(wpa_s, event, data); switch (event) { case EVENT_AUTH: #ifdef CONFIG_FST --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -367,6 +367,23 @@ static inline int hostapd_drv_stop_ap(st return hapd->driver->stop_ap(hapd->drv_priv); } +static inline int hostapd_drv_if_rename(struct hostapd_data *hapd, + enum wpa_driver_if_type type, + const char *ifname, + const char *new_name) +{ + if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv) + return -1; + return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name); +} + +static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd) +{ + if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv) + return 0; + return hapd->driver->set_first_bss(hapd->drv_priv); +} + static inline int hostapd_drv_channel_info(struct hostapd_data *hapd, struct wpa_channel_info *ci) { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -1224,7 +1224,7 @@ static void wpa_driver_nl80211_event_rtm } wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)", namebuf, ifname); - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) { + if (drv->first_bss->ifindex != ifi->ifi_index) { wpa_printf(MSG_DEBUG, "nl80211: Not the main interface (%s) - do not indicate interface down", drv->first_bss->ifname); @@ -1260,7 +1260,7 @@ static void wpa_driver_nl80211_event_rtm } wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)", namebuf, ifname); - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) { + if (drv->first_bss->ifindex != ifi->ifi_index) { wpa_printf(MSG_DEBUG, "nl80211: Not the main interface (%s) - do not indicate interface up", drv->first_bss->ifname); @@ -7614,6 +7614,7 @@ static void *i802_init(struct hostapd_da char master_ifname[IFNAMSIZ]; int ifindex, br_ifindex = 0; int br_added = 0; + int err; bss = wpa_driver_nl80211_drv_init(hapd, params->ifname, params->global_priv, 1, @@ -7673,21 +7674,17 @@ static void *i802_init(struct hostapd_da (params->num_bridge == 0 || !params->bridge[0])) add_ifidx(drv, br_ifindex, drv->ifindex); - if (bss->added_if_into_bridge || bss->already_in_bridge) { - int err; - - drv->rtnl_sk = nl_socket_alloc(); - if (drv->rtnl_sk == NULL) { - wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock"); - goto failed; - } + drv->rtnl_sk = nl_socket_alloc(); + if (drv->rtnl_sk == NULL) { + wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock"); + goto failed; + } - err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE); - if (err) { - wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s", - nl_geterror(err)); - goto failed; - } + err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE); + if (err) { + wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s", + nl_geterror(err)); + goto failed; } if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { @@ -8047,6 +8044,50 @@ static int wpa_driver_nl80211_if_remove( return 0; } +static int wpa_driver_nl80211_if_rename(struct i802_bss *bss, + enum wpa_driver_if_type type, + const char *ifname, const char *new_name) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct ifinfomsg ifi = { + .ifi_family = AF_UNSPEC, + .ifi_index = bss->ifindex, + }; + struct nl_msg *msg; + int res = -ENOMEM; + + if (ifname) + ifi.ifi_index = if_nametoindex(ifname); + + msg = nlmsg_alloc_simple(RTM_SETLINK, 0); + if (!msg) + return res; + + if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) + goto out; + + if (nla_put_string(msg, IFLA_IFNAME, new_name)) + goto out; + + res = nl_send_auto_complete(drv->rtnl_sk, msg); + if (res < 0) + goto out; + + res = nl_wait_for_ack(drv->rtnl_sk); + if (res) { + wpa_printf(MSG_INFO, + "nl80211: Renaming device %s to %s failed: %s", + ifname ? ifname : bss->ifname, new_name, nl_geterror(res)); + goto out; + } + + if (type == WPA_IF_AP_BSS && !ifname) + os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname)); + +out: + nlmsg_free(msg); + return res; +} static int cookie_handler(struct nl_msg *msg, void *arg) { @@ -9391,6 +9432,37 @@ static int driver_nl80211_if_remove(void } +static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type, + const char *ifname, const char *new_name) +{ + struct i802_bss *bss = priv; + return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name); +} + + +static int driver_nl80211_set_first_bss(void *priv) +{ + struct i802_bss *bss = priv, *tbss; + struct wpa_driver_nl80211_data *drv = bss->drv; + + if (drv->first_bss == bss) + return 0; + + for (tbss = drv->first_bss; tbss; tbss = tbss->next) { + if (tbss->next != bss) + continue; + + tbss->next = bss->next; + bss->next = drv->first_bss; + drv->first_bss = bss; + drv->ctx = bss->ctx; + return 0; + } + + return -1; +} + + static int driver_nl80211_send_mlme(void *priv, const u8 *data, size_t data_len, int noack, unsigned int freq, @@ -11973,6 +12045,8 @@ const struct wpa_driver_ops wpa_driver_n .set_acl = wpa_driver_nl80211_set_acl, .if_add = wpa_driver_nl80211_if_add, .if_remove = driver_nl80211_if_remove, + .if_rename = driver_nl80211_if_rename, + .set_first_bss = driver_nl80211_set_first_bss, .send_mlme = driver_nl80211_send_mlme, .get_hw_feature_data = nl80211_get_hw_feature_data, .sta_add = wpa_driver_nl80211_sta_add, --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -494,11 +494,17 @@ static const char * sae_get_password(str struct sae_pt **s_pt, const struct sae_pk **s_pk) { + struct hostapd_bss_config *conf = hapd->conf; + struct hostapd_ssid *ssid = &conf->ssid; + struct hostapd_sta_wpa_psk_short *psk; const char *password = NULL; - struct sae_password_entry *pw; + struct sae_password_entry *pw = NULL; struct sae_pt *pt = NULL; const struct sae_pk *pk = NULL; + if (sta && sta->use_sta_psk) + goto use_sta_psk; + for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) { if (!is_broadcast_ether_addr(pw->peer_addr) && os_memcmp(pw->peer_addr, sta->addr, ETH_ALEN) != 0) @@ -519,6 +525,33 @@ static const char * sae_get_password(str pt = hapd->conf->ssid.pt; } +use_sta_psk: + if (!password && sta) { + sta->psk_idx = 0; + for (psk = sta->psk; psk; psk = psk->next) { + if (!psk->is_passphrase) + continue; + + password = psk->passphrase; + if (!sta->use_sta_psk) + break; + + sta->psk_idx = 1; + if (sta->sae_pt) { + pt = sta->sae_pt; + break; + } + + pt = sae_derive_pt(conf->sae_groups, ssid->ssid, + ssid->ssid_len, + (const u8 *) password, + os_strlen(password), + NULL); + sta->sae_pt = pt; + break; + } + } + if (pw_entry) *pw_entry = pw; if (s_pt) @@ -3698,6 +3731,12 @@ static void handle_auth(struct hostapd_d goto fail; } + res = hostapd_ucode_sta_auth(hapd, sta); + if (res) { + resp = res; + goto fail; + } + sta->flags &= ~WLAN_STA_PREAUTH; ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -412,6 +412,9 @@ void ap_free_sta(struct hostapd_data *ha os_free(sta->sae_postponed_commit); #endif /* CONFIG_TESTING_OPTIONS */ + if (sta->sae_pt) + sae_deinit_pt(sta->sae_pt); + os_free(sta); } @@ -1280,6 +1283,8 @@ void ap_sta_set_authorized(struct hostap else sta->flags &= ~WLAN_STA_AUTHORIZED; + if (authorized) + hostapd_ucode_sta_connected(hapd, sta); #ifdef CONFIG_P2P if (hapd->p2p_group == NULL) { if (sta->p2p_ie != NULL && --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h @@ -201,6 +201,9 @@ struct sta_info { int vlan_id_bound; /* updated by ap_sta_bind_vlan() */ /* PSKs from RADIUS authentication server */ struct hostapd_sta_wpa_psk_short *psk; + struct sae_pt *sae_pt; + int use_sta_psk; + int psk_idx; char *identity; /* User-Name from RADIUS */ char *radius_cui; /* Chargeable-User-Identity from RADIUS */ --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -355,6 +355,7 @@ static const u8 * hostapd_wpa_auth_get_p } #endif /* CONFIG_SAE */ + sta->psk_idx = 0; #ifdef CONFIG_OWE if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) && sta && sta->owe_pmk) { @@ -381,12 +382,17 @@ static const u8 * hostapd_wpa_auth_get_p * returned psk which should not be returned again. * logic list (all hostapd_get_psk; all sta->psk) */ + if (sta && sta->use_sta_psk) + psk = NULL; if (sta && sta->psk && !psk) { struct hostapd_sta_wpa_psk_short *pos; + int psk_idx = 1; if (vlan_id) *vlan_id = 0; psk = sta->psk->psk; + if (vlan_id) + sta->psk_idx = psk_idx; for (pos = sta->psk; pos; pos = pos->next) { if (pos->is_passphrase) { pbkdf2_sha1(pos->passphrase, @@ -397,9 +403,13 @@ static const u8 * hostapd_wpa_auth_get_p } if (pos->psk == prev_psk) { psk = pos->next ? pos->next->psk : NULL; + if (vlan_id) + sta->psk_idx = psk_idx + 1; break; } } + if (vlan_id && !psk) + sta->psk_idx = 0; } return psk; }