mesh: Create new station entry on popen frames
Currently, there is a race in open mesh networks where mesh STA A receives a beacon from B and sends a peering open frame to initiate peering. STA B, having not yet received a beacon from A and thus created the corresponding station entry, will ignore all such open frames. If the beacon interval is sufficiently long then peering will not succeed as a result. In fact B can simply create the station entry when the popen is received, as is done in Linux's in-kernel MPM, avoiding the issue. Signed-off-by: Bob Copeland <me@bobcopeland.com>
This commit is contained in:
parent
41bff862d9
commit
745d93695b
1 changed files with 42 additions and 9 deletions
|
@ -519,27 +519,34 @@ void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
|
|||
mesh_mpm_plink_open(wpa_s, sta, PLINK_OPEN_SENT);
|
||||
}
|
||||
|
||||
|
||||
void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
|
||||
struct ieee802_11_elems *elems)
|
||||
/*
|
||||
* Initialize a sta_info structure for a peer and upload it into the driver
|
||||
* in preparation for beginning authentication or peering. This is done when a
|
||||
* Beacon (secure or open mesh) or a peering open frame (for open mesh) is
|
||||
* received from the peer for the first time.
|
||||
*/
|
||||
static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
|
||||
const u8 *addr,
|
||||
struct ieee802_11_elems *elems)
|
||||
{
|
||||
struct hostapd_sta_add_params params;
|
||||
struct mesh_conf *conf = wpa_s->ifmsh->mconf;
|
||||
struct hostapd_data *data = wpa_s->ifmsh->bss[0];
|
||||
struct sta_info *sta;
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
sta = ap_get_sta(data, addr);
|
||||
if (!sta) {
|
||||
sta = ap_sta_add(data, addr);
|
||||
if (!sta)
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initialize sta */
|
||||
if (copy_supp_rates(wpa_s, sta, elems))
|
||||
return;
|
||||
if (copy_supp_rates(wpa_s, sta, elems)) {
|
||||
ap_free_sta(data, sta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mesh_mpm_init_link(wpa_s, sta);
|
||||
|
||||
|
@ -573,9 +580,26 @@ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
|
|||
wpa_msg(wpa_s, MSG_ERROR,
|
||||
"Driver failed to insert " MACSTR ": %d",
|
||||
MAC2STR(addr), ret);
|
||||
return;
|
||||
ap_free_sta(data, sta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sta;
|
||||
}
|
||||
|
||||
|
||||
void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
|
||||
struct ieee802_11_elems *elems)
|
||||
{
|
||||
struct mesh_conf *conf = wpa_s->ifmsh->mconf;
|
||||
struct hostapd_data *data = wpa_s->ifmsh->bss[0];
|
||||
struct sta_info *sta;
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
|
||||
sta = mesh_mpm_add_peer(wpa_s, addr, elems);
|
||||
if (!sta)
|
||||
return;
|
||||
|
||||
if (ssid && ssid->no_auto_peer) {
|
||||
wpa_msg(wpa_s, MSG_INFO, "will not initiate new peer link with "
|
||||
MACSTR " because of no_auto_peer", MAC2STR(addr));
|
||||
|
@ -928,6 +952,15 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
|
|||
wpa_printf(MSG_DEBUG, "MPM: plid=0x%x llid=0x%x", plid, llid);
|
||||
|
||||
sta = ap_get_sta(hapd, mgmt->sa);
|
||||
|
||||
/*
|
||||
* If this is an open frame from an unknown STA, and this is an
|
||||
* open mesh, then go ahead and add the peer before proceeding.
|
||||
*/
|
||||
if (!sta && action_field == PLINK_OPEN &&
|
||||
!(mconf->security & MESH_CONF_SEC_AMPE))
|
||||
sta = mesh_mpm_add_peer(wpa_s, mgmt->sa, &elems);
|
||||
|
||||
if (!sta) {
|
||||
wpa_printf(MSG_DEBUG, "MPM: No STA entry for peer");
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue