diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 9112f2b81..c9871d9a6 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -55,6 +55,7 @@ static int wpa_ft_rrb_send(struct wpa_authenticator *wpa_auth, const u8 *dst, { if (wpa_auth->cb.send_ether == NULL) return -1; + wpa_printf(MSG_DEBUG, "FT: RRB send to " MACSTR, MAC2STR(dst)); return wpa_auth->cb.send_ether(wpa_auth->cb.ctx, dst, ETH_P_RRB, data, data_len); } diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index fdaf21467..afa13a698 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -31,6 +31,12 @@ #include "wpa_auth.h" +#ifdef CONFIG_IEEE80211R +static void hostapd_rrb_receive(void *ctx, const u8 *src_addr, const u8 *buf, + size_t len); +#endif /* CONFIG_IEEE80211R */ + + static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, struct wpa_auth_config *wconf) { @@ -294,11 +300,66 @@ static int hostapd_wpa_auth_for_each_auth( } +#ifdef CONFIG_IEEE80211R + +struct wpa_auth_ft_iface_iter_data { + struct hostapd_data *src_hapd; + const u8 *dst; + const u8 *data; + size_t data_len; +}; + + +static int hostapd_wpa_auth_ft_iter(struct hostapd_iface *iface, void *ctx) +{ + struct wpa_auth_ft_iface_iter_data *idata = ctx; + struct hostapd_data *hapd; + size_t j; + + for (j = 0; j < iface->num_bss; j++) { + hapd = iface->bss[j]; + if (hapd == idata->src_hapd) + continue; + if (os_memcmp(hapd->own_addr, idata->dst, ETH_ALEN) == 0) { + wpa_printf(MSG_DEBUG, "FT: Send RRB data directly to " + "locally managed BSS " MACSTR "@%s -> " + MACSTR "@%s", + MAC2STR(idata->src_hapd->own_addr), + idata->src_hapd->conf->iface, + MAC2STR(hapd->own_addr), hapd->conf->iface); + hostapd_rrb_receive(hapd, idata->src_hapd->own_addr, + idata->data, idata->data_len); + return 1; + } + } + + return 0; +} + +#endif /* CONFIG_IEEE80211R */ + + static int hostapd_wpa_auth_send_ether(void *ctx, const u8 *dst, u16 proto, const u8 *data, size_t data_len) { struct hostapd_data *hapd = ctx; +#ifdef CONFIG_IEEE80211R + if (proto == ETH_P_RRB && hapd->iface->for_each_interface) { + int res; + struct wpa_auth_ft_iface_iter_data idata; + idata.src_hapd = hapd; + idata.dst = dst; + idata.data = data; + idata.data_len = data_len; + res = hapd->iface->for_each_interface(hapd->iface->interfaces, + hostapd_wpa_auth_ft_iter, + &idata); + if (res == 1) + return data_len; + } +#endif /* CONFIG_IEEE80211R */ + if (hapd->driver && hapd->driver->send_ether) return hapd->driver->send_ether(hapd->drv_priv, dst, hapd->own_addr, proto,