FT: Send RRB data directly when managed by same hostapd process

This makes it easier (and a bit faster) to handle multiple local
radios with FT. There is no need to depend on l2_packet in that
case since the frame can be delivered as a direct function call.
This commit is contained in:
Jouni Malinen 2010-07-25 20:30:12 -07:00
parent 08b19cb404
commit 67ccef7e6c
2 changed files with 62 additions and 0 deletions

View file

@ -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) if (wpa_auth->cb.send_ether == NULL)
return -1; 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, return wpa_auth->cb.send_ether(wpa_auth->cb.ctx, dst, ETH_P_RRB,
data, data_len); data, data_len);
} }

View file

@ -31,6 +31,12 @@
#include "wpa_auth.h" #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, static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
struct wpa_auth_config *wconf) 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, static int hostapd_wpa_auth_send_ether(void *ctx, const u8 *dst, u16 proto,
const u8 *data, size_t data_len) const u8 *data, size_t data_len)
{ {
struct hostapd_data *hapd = ctx; 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) if (hapd->driver && hapd->driver->send_ether)
return hapd->driver->send_ether(hapd->drv_priv, dst, return hapd->driver->send_ether(hapd->drv_priv, dst,
hapd->own_addr, proto, hapd->own_addr, proto,